ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

wordpad.c
Go to the documentation of this file.
00001 /*
00002  * Wordpad implementation
00003  *
00004  * Copyright 2004 by Krzysztof Foltman
00005  * Copyright 2007-2008 by Alexander N. Sørnes <alex@thehandofagony.com>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #define WIN32_LEAN_AND_MEAN
00023 #define _WIN32_IE 0x0400
00024 
00025 #include <stdarg.h>
00026 #include <stdlib.h>
00027 #include <ctype.h>
00028 #include <stdio.h>
00029 #include <assert.h>
00030 
00031 #include <windows.h>
00032 #include <richedit.h>
00033 #include <commctrl.h>
00034 #include <commdlg.h>
00035 #include <shellapi.h>
00036 #include <math.h>
00037 #include <errno.h>
00038 
00039 #include "wine/unicode.h"
00040 #include "wordpad.h"
00041 
00042 #ifdef NONAMELESSUNION
00043 # define U(x)  (x).u
00044 # define U2(x) (x).u2
00045 # define U3(x) (x).u3
00046 #else
00047 # define U(x)  (x)
00048 # define U2(x) (x)
00049 # define U3(x) (x)
00050 #endif
00051 
00052 /* use LoadString */
00053 static const WCHAR wszAppTitle[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
00054 
00055 static const WCHAR wszMainWndClass[] = {'W','O','R','D','P','A','D','T','O','P',0};
00056 
00057 static const WCHAR stringFormat[] = {'%','2','d','\0'};
00058 
00059 const WCHAR wszPreviewWndClass[] = {'P','r','t','P','r','e','v','i','e','w',0};
00060 LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
00061 
00062 static HWND hMainWnd;
00063 static HWND hEditorWnd;
00064 static HWND hFindWnd;
00065 static HMENU hColorPopupMenu;
00066 
00067 static UINT ID_FINDMSGSTRING;
00068 
00069 static DWORD wordWrap[2];
00070 static DWORD barState[2];
00071 static WPARAM fileFormat = SF_RTF;
00072 
00073 static WCHAR wszFileName[MAX_PATH];
00074 static WCHAR wszFilter[MAX_STRING_LEN*4+6*3+5];
00075 static WCHAR wszDefaultFileName[MAX_STRING_LEN];
00076 static WCHAR wszSaveChanges[MAX_STRING_LEN];
00077 static WCHAR units_cmW[MAX_STRING_LEN];
00078 static WCHAR units_inW[MAX_STRING_LEN];
00079 static WCHAR units_inchW[MAX_STRING_LEN];
00080 static WCHAR units_ptW[MAX_STRING_LEN];
00081 
00082 static LRESULT OnSize( HWND hWnd, WPARAM wParam, LPARAM lParam );
00083 
00084 typedef enum
00085 {
00086     UNIT_CM,
00087     UNIT_INCH,
00088     UNIT_PT
00089 } UNIT;
00090 
00091 typedef struct
00092 {
00093     int endPos;
00094     BOOL wrapped;
00095     WCHAR findBuffer[128];
00096 } FINDREPLACE_custom;
00097 
00098 /* Load string resources */
00099 static void DoLoadStrings(void)
00100 {
00101     LPWSTR p = wszFilter;
00102     static const WCHAR files_rtf[] = {'*','.','r','t','f','\0'};
00103     static const WCHAR files_txt[] = {'*','.','t','x','t','\0'};
00104     static const WCHAR files_all[] = {'*','.','*','\0'};
00105 
00106     HINSTANCE hInstance = GetModuleHandleW(0);
00107 
00108     LoadStringW(hInstance, STRING_RICHTEXT_FILES_RTF, p, MAX_STRING_LEN);
00109     p += lstrlenW(p) + 1;
00110     lstrcpyW(p, files_rtf);
00111     p += lstrlenW(p) + 1;
00112     LoadStringW(hInstance, STRING_TEXT_FILES_TXT, p, MAX_STRING_LEN);
00113     p += lstrlenW(p) + 1;
00114     lstrcpyW(p, files_txt);
00115     p += lstrlenW(p) + 1;
00116     LoadStringW(hInstance, STRING_TEXT_FILES_UNICODE_TXT, p, MAX_STRING_LEN);
00117     p += lstrlenW(p) + 1;
00118     lstrcpyW(p, files_txt);
00119     p += lstrlenW(p) + 1;
00120     LoadStringW(hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN);
00121     p += lstrlenW(p) + 1;
00122     lstrcpyW(p, files_all);
00123     p += lstrlenW(p) + 1;
00124     *p = '\0';
00125 
00126     p = wszDefaultFileName;
00127     LoadStringW(hInstance, STRING_DEFAULT_FILENAME, p, MAX_STRING_LEN);
00128 
00129     p = wszSaveChanges;
00130     LoadStringW(hInstance, STRING_PROMPT_SAVE_CHANGES, p, MAX_STRING_LEN);
00131 
00132     LoadStringW(hInstance, STRING_UNITS_CM, units_cmW, MAX_STRING_LEN);
00133     LoadStringW(hInstance, STRING_UNITS_IN, units_inW, MAX_STRING_LEN);
00134     LoadStringW(hInstance, STRING_UNITS_INCH, units_inchW, MAX_STRING_LEN);
00135     LoadStringW(hInstance, STRING_UNITS_PT, units_ptW, MAX_STRING_LEN);
00136 }
00137 
00138 /* Show a message box with resource strings */
00139 static int MessageBoxWithResStringW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
00140 {
00141     MSGBOXPARAMSW params;
00142 
00143     params.cbSize             = sizeof(params);
00144     params.hwndOwner          = hWnd;
00145     params.hInstance          = GetModuleHandleW(0);
00146     params.lpszText           = lpText;
00147     params.lpszCaption        = lpCaption;
00148     params.dwStyle            = uType;
00149     params.lpszIcon           = NULL;
00150     params.dwContextHelpId    = 0;
00151     params.lpfnMsgBoxCallback = NULL;
00152     params.dwLanguageId       = 0;
00153     return MessageBoxIndirectW(&params);
00154 }
00155 
00156 
00157 static void AddButton(HWND hwndToolBar, int nImage, int nCommand)
00158 {
00159     TBBUTTON button;
00160 
00161     ZeroMemory(&button, sizeof(button));
00162     button.iBitmap = nImage;
00163     button.idCommand = nCommand;
00164     button.fsState = TBSTATE_ENABLED;
00165     button.fsStyle = BTNS_BUTTON;
00166     button.dwData = 0;
00167     button.iString = -1;
00168     SendMessageW(hwndToolBar, TB_ADDBUTTONSW, 1, (LPARAM)&button);
00169 }
00170 
00171 static void AddSeparator(HWND hwndToolBar)
00172 {
00173     TBBUTTON button;
00174 
00175     ZeroMemory(&button, sizeof(button));
00176     button.iBitmap = -1;
00177     button.idCommand = 0;
00178     button.fsState = 0;
00179     button.fsStyle = BTNS_SEP;
00180     button.dwData = 0;
00181     button.iString = -1;
00182     SendMessageW(hwndToolBar, TB_ADDBUTTONSW, 1, (LPARAM)&button);
00183 }
00184 
00185 static DWORD CALLBACK stream_in(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb)
00186 {
00187     HANDLE hFile = (HANDLE)cookie;
00188     DWORD read;
00189 
00190     if(!ReadFile(hFile, buffer, cb, &read, 0))
00191         return 1;
00192 
00193     *pcb = read;
00194 
00195     return 0;
00196 }
00197 
00198 static DWORD CALLBACK stream_out(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb)
00199 {
00200     DWORD written;
00201     int ret;
00202     HANDLE hFile = (HANDLE)cookie;
00203 
00204     ret = WriteFile(hFile, buffer, cb, &written, 0);
00205 
00206     if(!ret || (cb != written))
00207         return 1;
00208 
00209     *pcb = cb;
00210 
00211     return 0;
00212 }
00213 
00214 LPWSTR file_basename(LPWSTR path)
00215 {
00216     LPWSTR pos = path + lstrlenW(path);
00217 
00218     while(pos > path)
00219     {
00220         if(*pos == '\\' || *pos == '/')
00221         {
00222             pos++;
00223             break;
00224         }
00225         pos--;
00226     }
00227     return pos;
00228 }
00229 
00230 static void set_caption(LPCWSTR wszNewFileName)
00231 {
00232     static const WCHAR wszSeparator[] = {' ','-',' '};
00233     WCHAR *wszCaption;
00234     SIZE_T length = 0;
00235 
00236     if(!wszNewFileName)
00237         wszNewFileName = wszDefaultFileName;
00238     else
00239         wszNewFileName = file_basename((LPWSTR)wszNewFileName);
00240 
00241     wszCaption = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
00242                 lstrlenW(wszNewFileName)*sizeof(WCHAR)+sizeof(wszSeparator)+sizeof(wszAppTitle));
00243 
00244     if(!wszCaption)
00245         return;
00246 
00247     memcpy(wszCaption, wszNewFileName, lstrlenW(wszNewFileName)*sizeof(WCHAR));
00248     length += lstrlenW(wszNewFileName);
00249     memcpy(wszCaption + length, wszSeparator, sizeof(wszSeparator));
00250     length += sizeof(wszSeparator) / sizeof(WCHAR);
00251     memcpy(wszCaption + length, wszAppTitle, sizeof(wszAppTitle));
00252 
00253     SetWindowTextW(hMainWnd, wszCaption);
00254 
00255     HeapFree(GetProcessHeap(), 0, wszCaption);
00256 }
00257 
00258 static BOOL validate_endptr(LPCWSTR endptr, UNIT *punit)
00259 {
00260     if(punit != NULL)
00261         *punit = UNIT_CM;
00262     if(!endptr)
00263         return FALSE;
00264     if(!*endptr)
00265         return TRUE;
00266 
00267     while(*endptr == ' ')
00268         endptr++;
00269 
00270     if(punit == NULL)
00271         return *endptr == '\0';
00272 
00273     if(!lstrcmpW(endptr, units_cmW))
00274     {
00275         *punit = UNIT_CM;
00276         endptr += lstrlenW(units_cmW);
00277     }
00278     else if (!lstrcmpW(endptr, units_inW))
00279     {
00280         *punit = UNIT_INCH;
00281         endptr += lstrlenW(units_inW);
00282     }
00283     else if (!lstrcmpW(endptr, units_inchW))
00284     {
00285         *punit = UNIT_INCH;
00286         endptr += lstrlenW(units_inchW);
00287     }
00288     else if (!lstrcmpW(endptr, units_ptW))
00289     {
00290         *punit = UNIT_PT;
00291         endptr += lstrlenW(units_ptW);
00292     }
00293 
00294     return *endptr == '\0';
00295 }
00296 
00297 static BOOL number_from_string(LPCWSTR string, float *num, UNIT *punit)
00298 {
00299     double ret;
00300     WCHAR *endptr;
00301 
00302     *num = 0;
00303     errno = 0;
00304     ret = wcstod(string, &endptr);
00305 
00306     if (punit != NULL)
00307         *punit = UNIT_CM;
00308     if((ret == 0 && errno != 0) || endptr == string || !validate_endptr(endptr, punit))
00309     {
00310         return FALSE;
00311     } else
00312     {
00313         *num = (float)ret;
00314         return TRUE;
00315     }
00316 }
00317 
00318 static void set_size(float size)
00319 {
00320     CHARFORMAT2W fmt;
00321 
00322     ZeroMemory(&fmt, sizeof(fmt));
00323     fmt.cbSize = sizeof(fmt);
00324     fmt.dwMask = CFM_SIZE;
00325     fmt.yHeight = (int)(size * 20.0);
00326     SendMessageW(hEditorWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
00327 }
00328 
00329 static void on_sizelist_modified(HWND hwndSizeList, LPWSTR wszNewFontSize)
00330 {
00331     WCHAR sizeBuffer[MAX_STRING_LEN];
00332     CHARFORMAT2W format;
00333 
00334     ZeroMemory(&format, sizeof(format));
00335     format.cbSize = sizeof(format);
00336     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);
00337 
00338     wsprintfW(sizeBuffer, stringFormat, format.yHeight / 20);
00339     if(lstrcmpW(sizeBuffer, wszNewFontSize))
00340     {
00341         float size = 0;
00342         if(number_from_string(wszNewFontSize, &size, NULL)
00343            && size > 0)
00344         {
00345             set_size(size);
00346         } else
00347         {
00348             SetWindowTextW(hwndSizeList, sizeBuffer);
00349             MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_INVALID_NUMBER),
00350                         wszAppTitle, MB_OK | MB_ICONINFORMATION);
00351         }
00352     }
00353 }
00354 
00355 static void add_size(HWND hSizeListWnd, unsigned size)
00356 {
00357     WCHAR buffer[3];
00358     COMBOBOXEXITEMW cbItem;
00359     cbItem.mask = CBEIF_TEXT;
00360     cbItem.iItem = -1;
00361 
00362     wsprintfW(buffer, stringFormat, size);
00363     cbItem.pszText = buffer;
00364     SendMessageW(hSizeListWnd, CBEM_INSERTITEMW, 0, (LPARAM)&cbItem);
00365 }
00366 
00367 static void populate_size_list(HWND hSizeListWnd)
00368 {
00369     HWND hReBarWnd = GetDlgItem(hMainWnd, IDC_REBAR);
00370     HWND hFontListWnd = GetDlgItem(hReBarWnd, IDC_FONTLIST);
00371     COMBOBOXEXITEMW cbFontItem;
00372     CHARFORMAT2W fmt;
00373     HWND hListEditWnd = (HWND)SendMessageW(hSizeListWnd, CBEM_GETEDITCONTROL, 0, 0);
00374     HDC hdc = GetDC(hMainWnd);
00375     static const unsigned choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
00376     WCHAR buffer[3];
00377     size_t i;
00378     DWORD fontStyle;
00379 
00380     ZeroMemory(&fmt, sizeof(fmt));
00381     fmt.cbSize = sizeof(fmt);
00382     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
00383 
00384     cbFontItem.mask = CBEIF_LPARAM;
00385     cbFontItem.iItem = SendMessageW(hFontListWnd, CB_FINDSTRINGEXACT, -1, (LPARAM)fmt.szFaceName);
00386     SendMessageW(hFontListWnd, CBEM_GETITEMW, 0, (LPARAM)&cbFontItem);
00387 
00388     fontStyle = (DWORD)LOWORD(cbFontItem.lParam);
00389 
00390     SendMessageW(hSizeListWnd, CB_RESETCONTENT, 0, 0);
00391 
00392     if((fontStyle & RASTER_FONTTYPE) && cbFontItem.iItem)
00393     {
00394         add_size(hSizeListWnd, (BYTE)MulDiv(HIWORD(cbFontItem.lParam), 72,
00395                                GetDeviceCaps(hdc, LOGPIXELSY)));
00396     } else
00397     {
00398         for(i = 0; i < sizeof(choices)/sizeof(choices[0]); i++)
00399             add_size(hSizeListWnd, choices[i]);
00400     }
00401 
00402     wsprintfW(buffer, stringFormat, fmt.yHeight / 20);
00403     SendMessageW(hListEditWnd, WM_SETTEXT, 0, (LPARAM)buffer);
00404 }
00405 
00406 static void update_size_list(void)
00407 {
00408     HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
00409     HWND hwndSizeList = GetDlgItem(hReBar, IDC_SIZELIST);
00410     HWND hwndSizeListEdit = (HWND)SendMessageW(hwndSizeList, CBEM_GETEDITCONTROL, 0, 0);
00411     WCHAR fontSize[MAX_STRING_LEN], sizeBuffer[MAX_STRING_LEN];
00412     CHARFORMAT2W fmt;
00413 
00414     ZeroMemory(&fmt, sizeof(fmt));
00415     fmt.cbSize = sizeof(fmt);
00416 
00417     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
00418 
00419     SendMessageW(hwndSizeListEdit, WM_GETTEXT, MAX_PATH, (LPARAM)fontSize);
00420     wsprintfW(sizeBuffer, stringFormat, fmt.yHeight / 20);
00421 
00422     if(lstrcmpW(fontSize, sizeBuffer))
00423         SendMessageW(hwndSizeListEdit, WM_SETTEXT, 0, (LPARAM)sizeBuffer);
00424 }
00425 
00426 static void update_font_list(void)
00427 {
00428     HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
00429     HWND hFontList = GetDlgItem(hReBar, IDC_FONTLIST);
00430     HWND hFontListEdit = (HWND)SendMessageW(hFontList, CBEM_GETEDITCONTROL, 0, 0);
00431     WCHAR fontName[MAX_STRING_LEN];
00432     CHARFORMAT2W fmt;
00433 
00434     ZeroMemory(&fmt, sizeof(fmt));
00435     fmt.cbSize = sizeof(fmt);
00436 
00437     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
00438     if (!SendMessageW(hFontListEdit, WM_GETTEXT, MAX_PATH, (LPARAM)fontName)) return;
00439 
00440     if(lstrcmpW(fontName, fmt.szFaceName))
00441     {
00442         SendMessageW(hFontListEdit, WM_SETTEXT, 0, (LPARAM)fmt.szFaceName);
00443         populate_size_list(GetDlgItem(hReBar, IDC_SIZELIST));
00444     } else
00445     {
00446         update_size_list();
00447     }
00448 }
00449 
00450 static void clear_formatting(void)
00451 {
00452     PARAFORMAT2 pf;
00453 
00454     pf.cbSize = sizeof(pf);
00455     pf.dwMask = PFM_ALIGNMENT;
00456     pf.wAlignment = PFA_LEFT;
00457     SendMessageW(hEditorWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
00458 }
00459 
00460 static int fileformat_number(WPARAM format)
00461 {
00462     int number = 0;
00463 
00464     if(format == SF_TEXT)
00465     {
00466         number = 1;
00467     } else if (format == (SF_TEXT | SF_UNICODE))
00468     {
00469         number = 2;
00470     }
00471     return number;
00472 }
00473 
00474 static WPARAM fileformat_flags(int format)
00475 {
00476     WPARAM flags[] = { SF_RTF , SF_TEXT , SF_TEXT | SF_UNICODE };
00477 
00478     return flags[format];
00479 }
00480 
00481 static void set_font(LPCWSTR wszFaceName)
00482 {
00483     HWND hReBarWnd = GetDlgItem(hMainWnd, IDC_REBAR);
00484     HWND hSizeListWnd = GetDlgItem(hReBarWnd, IDC_SIZELIST);
00485     HWND hFontListWnd = GetDlgItem(hReBarWnd, IDC_FONTLIST);
00486     HWND hFontListEditWnd = (HWND)SendMessageW(hFontListWnd, CBEM_GETEDITCONTROL, 0, 0);
00487     CHARFORMAT2W fmt;
00488 
00489     ZeroMemory(&fmt, sizeof(fmt));
00490 
00491     fmt.cbSize = sizeof(fmt);
00492     fmt.dwMask = CFM_FACE;
00493 
00494     lstrcpyW(fmt.szFaceName, wszFaceName);
00495 
00496     SendMessageW(hEditorWnd, EM_SETCHARFORMAT,  SCF_SELECTION, (LPARAM)&fmt);
00497 
00498     populate_size_list(hSizeListWnd);
00499 
00500     SendMessageW(hFontListEditWnd, WM_SETTEXT, 0, (LPARAM)wszFaceName);
00501 }
00502 
00503 static void set_default_font(void)
00504 {
00505     static const WCHAR richTextFont[] = {'T','i','m','e','s',' ','N','e','w',' ',
00506                                          'R','o','m','a','n',0};
00507     static const WCHAR plainTextFont[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
00508     CHARFORMAT2W fmt;
00509     LPCWSTR font;
00510 
00511     ZeroMemory(&fmt, sizeof(fmt));
00512 
00513     fmt.cbSize = sizeof(fmt);
00514     fmt.dwMask = CFM_FACE | CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
00515     fmt.dwEffects = 0;
00516 
00517     if(fileFormat & SF_RTF)
00518         font = richTextFont;
00519     else
00520         font = plainTextFont;
00521 
00522     lstrcpyW(fmt.szFaceName, font);
00523 
00524     SendMessageW(hEditorWnd, EM_SETCHARFORMAT,  SCF_DEFAULT, (LPARAM)&fmt);
00525 }
00526 
00527 static void on_fontlist_modified(LPWSTR wszNewFaceName)
00528 {
00529     CHARFORMAT2W format;
00530     ZeroMemory(&format, sizeof(format));
00531     format.cbSize = sizeof(format);
00532     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);
00533 
00534     if(lstrcmpW(format.szFaceName, wszNewFaceName))
00535         set_font(wszNewFaceName);
00536 }
00537 
00538 static void add_font(LPCWSTR fontName, DWORD fontType, HWND hListWnd, const NEWTEXTMETRICEXW *ntmc)
00539 {
00540     COMBOBOXEXITEMW cbItem;
00541     WCHAR buffer[MAX_PATH];
00542     int fontHeight = 0;
00543 
00544     cbItem.mask = CBEIF_TEXT;
00545     cbItem.pszText = buffer;
00546     cbItem.cchTextMax = MAX_STRING_LEN;
00547     cbItem.iItem = 0;
00548 
00549     while(SendMessageW(hListWnd, CBEM_GETITEMW, 0, (LPARAM)&cbItem))
00550     {
00551         if(lstrcmpiW(cbItem.pszText, fontName) <= 0)
00552             cbItem.iItem++;
00553         else
00554             break;
00555     }
00556     cbItem.pszText = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(fontName) + 1)*sizeof(WCHAR) );
00557     lstrcpyW( cbItem.pszText, fontName );
00558 
00559     cbItem.mask |= CBEIF_LPARAM;
00560     if(fontType & RASTER_FONTTYPE)
00561         fontHeight = ntmc->ntmTm.tmHeight - ntmc->ntmTm.tmInternalLeading;
00562 
00563     cbItem.lParam = MAKELONG(fontType,fontHeight);
00564     SendMessageW(hListWnd, CBEM_INSERTITEMW, 0, (LPARAM)&cbItem);
00565     HeapFree( GetProcessHeap(), 0, cbItem.pszText );
00566 }
00567 
00568 static void dialog_choose_font(void)
00569 {
00570     CHOOSEFONTW cf;
00571     LOGFONTW lf;
00572     CHARFORMAT2W fmt;
00573     HDC hDC = GetDC(hMainWnd);
00574 
00575     ZeroMemory(&cf, sizeof(cf));
00576     cf.lStructSize = sizeof(cf);
00577     cf.hwndOwner = hMainWnd;
00578     cf.lpLogFont = &lf;
00579     cf.Flags = CF_SCREENFONTS | CF_NOSCRIPTSEL | CF_INITTOLOGFONTSTRUCT | CF_EFFECTS;
00580 
00581     ZeroMemory(&fmt, sizeof(fmt));
00582     fmt.cbSize = sizeof(fmt);
00583 
00584     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
00585     lstrcpyW(cf.lpLogFont->lfFaceName, fmt.szFaceName);
00586     cf.lpLogFont->lfItalic = (fmt.dwEffects & CFE_ITALIC) ? TRUE : FALSE;
00587     cf.lpLogFont->lfWeight = (fmt.dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
00588     cf.lpLogFont->lfUnderline = (fmt.dwEffects & CFE_UNDERLINE) ? TRUE : FALSE;
00589     cf.lpLogFont->lfStrikeOut = (fmt.dwEffects & CFE_STRIKEOUT) ? TRUE : FALSE;
00590     cf.lpLogFont->lfHeight = -MulDiv(fmt.yHeight / 20, GetDeviceCaps(hDC, LOGPIXELSY), 72);
00591     cf.rgbColors = fmt.crTextColor;
00592 
00593     if(ChooseFontW(&cf))
00594     {
00595         ZeroMemory(&fmt, sizeof(fmt));
00596         fmt.cbSize = sizeof(fmt);
00597         fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR;
00598         fmt.yHeight = cf.iPointSize * 2;
00599 
00600         if(cf.nFontType & BOLD_FONTTYPE)
00601             fmt.dwEffects |= CFE_BOLD;
00602         if(cf.nFontType & ITALIC_FONTTYPE)
00603             fmt.dwEffects |= CFE_ITALIC;
00604         if(cf.lpLogFont->lfUnderline == TRUE)
00605             fmt.dwEffects |= CFE_UNDERLINE;
00606         if(cf.lpLogFont->lfStrikeOut == TRUE)
00607             fmt.dwEffects |= CFE_STRIKEOUT;
00608 
00609         fmt.crTextColor = cf.rgbColors;
00610 
00611         SendMessageW(hEditorWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
00612         set_font(cf.lpLogFont->lfFaceName);
00613     }
00614 }
00615 
00616 
00617 static int CALLBACK enum_font_proc(const LOGFONTW *lpelfe, const TEXTMETRICW *lpntme,
00618                             DWORD FontType, LPARAM lParam)
00619 {
00620     HWND hListWnd = (HWND) lParam;
00621 
00622     if(SendMessageW(hListWnd, CB_FINDSTRINGEXACT, -1, (LPARAM)lpelfe->lfFaceName) == CB_ERR)
00623     {
00624 
00625         add_font(lpelfe->lfFaceName, FontType, hListWnd, (const NEWTEXTMETRICEXW*)lpntme);
00626     }
00627 
00628     return 1;
00629 }
00630 
00631 static void populate_font_list(HWND hListWnd)
00632 {
00633     HDC hdc = GetDC(hMainWnd);
00634     LOGFONTW fontinfo;
00635     HWND hListEditWnd = (HWND)SendMessageW(hListWnd, CBEM_GETEDITCONTROL, 0, 0);
00636     CHARFORMAT2W fmt;
00637 
00638     fontinfo.lfCharSet = DEFAULT_CHARSET;
00639     *fontinfo.lfFaceName = '\0';
00640     fontinfo.lfPitchAndFamily = 0;
00641 
00642     EnumFontFamiliesExW(hdc, &fontinfo, enum_font_proc,
00643                         (LPARAM)hListWnd, 0);
00644 
00645     ZeroMemory(&fmt, sizeof(fmt));
00646     fmt.cbSize = sizeof(fmt);
00647     SendMessageW(hEditorWnd, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&fmt);
00648     SendMessageW(hListEditWnd, WM_SETTEXT, 0, (LPARAM)fmt.szFaceName);
00649 }
00650 
00651 static void update_window(void)
00652 {
00653     RECT rect;
00654 
00655     GetClientRect(hMainWnd, &rect);
00656 
00657     OnSize(hMainWnd, SIZE_RESTORED, MAKELPARAM(rect.right, rect.bottom));
00658 }
00659 
00660 static BOOL is_bar_visible(int bandId)
00661 {
00662     return barState[reg_formatindex(fileFormat)] & (1 << bandId);
00663 }
00664 
00665 static void store_bar_state(int bandId, BOOL show)
00666 {
00667     int formatIndex = reg_formatindex(fileFormat);
00668 
00669     if(show)
00670         barState[formatIndex] |= (1 << bandId);
00671     else
00672         barState[formatIndex] &= ~(1 << bandId);
00673 }
00674 
00675 static void set_toolbar_state(int bandId, BOOL show)
00676 {
00677     HWND hwndReBar = GetDlgItem(hMainWnd, IDC_REBAR);
00678 
00679     SendMessageW(hwndReBar, RB_SHOWBAND, SendMessageW(hwndReBar, RB_IDTOINDEX, bandId, 0), show);
00680 
00681     if(bandId == BANDID_TOOLBAR)
00682     {
00683         REBARBANDINFOW rbbinfo;
00684         int index = SendMessageW(hwndReBar, RB_IDTOINDEX, BANDID_FONTLIST, 0);
00685 
00686         rbbinfo.cbSize = REBARBANDINFOW_V6_SIZE;
00687         rbbinfo.fMask = RBBIM_STYLE;
00688 
00689         SendMessageW(hwndReBar, RB_GETBANDINFO, index, (LPARAM)&rbbinfo);
00690 
00691         if(!show)
00692             rbbinfo.fStyle &= ~RBBS_BREAK;
00693         else
00694             rbbinfo.fStyle |= RBBS_BREAK;
00695 
00696         SendMessageW(hwndReBar, RB_SETBANDINFO, index, (LPARAM)&rbbinfo);
00697     }
00698 
00699     if(bandId == BANDID_TOOLBAR || bandId == BANDID_FORMATBAR || bandId == BANDID_RULER)
00700         store_bar_state(bandId, show);
00701 }
00702 
00703 static void set_statusbar_state(BOOL show)
00704 {
00705     HWND hStatusWnd = GetDlgItem(hMainWnd, IDC_STATUSBAR);
00706 
00707     ShowWindow(hStatusWnd, show ? SW_SHOW : SW_HIDE);
00708     store_bar_state(BANDID_STATUSBAR, show);
00709 }
00710 
00711 static void set_bar_states(void)
00712 {
00713     set_toolbar_state(BANDID_TOOLBAR, is_bar_visible(BANDID_TOOLBAR));
00714     set_toolbar_state(BANDID_FONTLIST, is_bar_visible(BANDID_FORMATBAR));
00715     set_toolbar_state(BANDID_SIZELIST, is_bar_visible(BANDID_FORMATBAR));
00716     set_toolbar_state(BANDID_FORMATBAR, is_bar_visible(BANDID_FORMATBAR));
00717     set_toolbar_state(BANDID_RULER, is_bar_visible(BANDID_RULER));
00718     set_statusbar_state(is_bar_visible(BANDID_STATUSBAR));
00719 
00720     update_window();
00721 }
00722 
00723 static void preview_exit(HWND hMainWnd)
00724 {
00725     HMENU hMenu = LoadMenuW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDM_MAINMENU));
00726     HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
00727 
00728     set_bar_states();
00729     ShowWindow(hEditorWnd, TRUE);
00730 
00731     close_preview(hMainWnd);
00732 
00733     SetMenu(hMainWnd, hMenu);
00734     registry_read_filelist(hMainWnd);
00735 
00736     update_window();
00737 }
00738 
00739 static void set_fileformat(WPARAM format)
00740 {
00741     fileFormat = format;
00742 
00743     set_bar_states();
00744     set_default_font();
00745     target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
00746 }
00747 
00748 static void ShowOpenError(DWORD Code)
00749 {
00750     LPWSTR Message;
00751 
00752     switch(Code)
00753     {
00754         case ERROR_ACCESS_DENIED:
00755             Message = MAKEINTRESOURCEW(STRING_OPEN_ACCESS_DENIED);
00756             break;
00757 
00758         default:
00759             Message = MAKEINTRESOURCEW(STRING_OPEN_FAILED);
00760     }
00761     MessageBoxW(hMainWnd, Message, wszAppTitle, MB_ICONEXCLAMATION | MB_OK);
00762 }
00763 
00764 static void DoOpenFile(LPCWSTR szOpenFileName)
00765 {
00766     HANDLE hFile;
00767     EDITSTREAM es;
00768     char fileStart[5];
00769     DWORD readOut;
00770     WPARAM format = SF_TEXT;
00771 
00772     hFile = CreateFileW(szOpenFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
00773                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00774     if (hFile == INVALID_HANDLE_VALUE)
00775     {
00776         ShowOpenError(GetLastError());
00777         return;
00778     }
00779 
00780     ReadFile(hFile, fileStart, 5, &readOut, NULL);
00781     SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
00782 
00783     if(readOut >= 2 && (BYTE)fileStart[0] == 0xff && (BYTE)fileStart[1] == 0xfe)
00784     {
00785         format = SF_TEXT | SF_UNICODE;
00786         SetFilePointer(hFile, 2, NULL, FILE_BEGIN);
00787     } else if(readOut >= 5)
00788     {
00789         static const char header[] = "{\\rtf";
00790         static const BYTE STG_magic[] = { 0xd0,0xcf,0x11,0xe0 };
00791 
00792         if(!memcmp(header, fileStart, 5))
00793             format = SF_RTF;
00794         else if (!memcmp(STG_magic, fileStart, sizeof(STG_magic)))
00795         {
00796             CloseHandle(hFile);
00797             MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_OLE_STORAGE_NOT_SUPPORTED),
00798                     wszAppTitle, MB_OK | MB_ICONEXCLAMATION);
00799             return;
00800         }
00801     }
00802 
00803     es.dwCookie = (DWORD_PTR)hFile;
00804     es.pfnCallback = stream_in;
00805 
00806     clear_formatting();
00807     set_fileformat(format);
00808     SendMessageW(hEditorWnd, EM_STREAMIN, format, (LPARAM)&es);
00809 
00810     CloseHandle(hFile);
00811 
00812     SetFocus(hEditorWnd);
00813 
00814     set_caption(szOpenFileName);
00815 
00816     lstrcpyW(wszFileName, szOpenFileName);
00817     SendMessageW(hEditorWnd, EM_SETMODIFY, FALSE, 0);
00818     registry_set_filelist(szOpenFileName, hMainWnd);
00819     update_font_list();
00820 }
00821 
00822 static void ShowWriteError(DWORD Code)
00823 {
00824     LPWSTR Message;
00825 
00826     switch(Code)
00827     {
00828         case ERROR_ACCESS_DENIED:
00829             Message = MAKEINTRESOURCEW(STRING_WRITE_ACCESS_DENIED);
00830             break;
00831 
00832         default:
00833             Message = MAKEINTRESOURCEW(STRING_WRITE_FAILED);
00834     }
00835     MessageBoxW(hMainWnd, Message, wszAppTitle, MB_ICONEXCLAMATION | MB_OK);
00836 }
00837 
00838 static void DoSaveFile(LPCWSTR wszSaveFileName, WPARAM format)
00839 {
00840     HANDLE hFile;
00841     EDITSTREAM stream;
00842     LRESULT ret;
00843 
00844     hFile = CreateFileW(wszSaveFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
00845         FILE_ATTRIBUTE_NORMAL, NULL);
00846 
00847     if(hFile == INVALID_HANDLE_VALUE)
00848     {
00849         ShowWriteError(GetLastError());
00850         return;
00851     }
00852 
00853     if(format == (SF_TEXT | SF_UNICODE))
00854     {
00855         static const BYTE unicode[] = {0xff,0xfe};
00856         DWORD writeOut;
00857         WriteFile(hFile, &unicode, sizeof(unicode), &writeOut, 0);
00858 
00859         if(writeOut != sizeof(unicode))
00860         {
00861             CloseHandle(hFile);
00862             return;
00863         }
00864     }
00865 
00866     stream.dwCookie = (DWORD_PTR)hFile;
00867     stream.pfnCallback = stream_out;
00868 
00869     ret = SendMessageW(hEditorWnd, EM_STREAMOUT, format, (LPARAM)&stream);
00870 
00871     CloseHandle(hFile);
00872 
00873     SetFocus(hEditorWnd);
00874 
00875     if(!ret)
00876     {
00877         GETTEXTLENGTHEX gt;
00878         gt.flags = GTL_DEFAULT;
00879         gt.codepage = 1200;
00880 
00881         if(SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0))
00882             return;
00883     }
00884 
00885     lstrcpyW(wszFileName, wszSaveFileName);
00886     set_caption(wszFileName);
00887     SendMessageW(hEditorWnd, EM_SETMODIFY, FALSE, 0);
00888     set_fileformat(format);
00889 }
00890 
00891 static void DialogSaveFile(void)
00892 {
00893     OPENFILENAMEW sfn;
00894 
00895     WCHAR wszFile[MAX_PATH] = {'\0'};
00896     static const WCHAR wszDefExt[] = {'r','t','f','\0'};
00897 
00898     ZeroMemory(&sfn, sizeof(sfn));
00899 
00900     sfn.lStructSize = sizeof(sfn);
00901     sfn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_ENABLESIZING;
00902     sfn.hwndOwner = hMainWnd;
00903     sfn.lpstrFilter = wszFilter;
00904     sfn.lpstrFile = wszFile;
00905     sfn.nMaxFile = MAX_PATH;
00906     sfn.lpstrDefExt = wszDefExt;
00907     sfn.nFilterIndex = fileformat_number(fileFormat)+1;
00908 
00909     while(GetSaveFileNameW(&sfn))
00910     {
00911         if(fileformat_flags(sfn.nFilterIndex-1) != SF_RTF)
00912         {
00913             if(MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_SAVE_LOSEFORMATTING),
00914                            wszAppTitle, MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
00915             {
00916                 continue;
00917             } else
00918             {
00919                 DoSaveFile(sfn.lpstrFile, fileformat_flags(sfn.nFilterIndex-1));
00920                 break;
00921             }
00922         } else
00923         {
00924             DoSaveFile(sfn.lpstrFile, fileformat_flags(sfn.nFilterIndex-1));
00925             break;
00926         }
00927     }
00928 }
00929 
00930 static BOOL prompt_save_changes(void)
00931 {
00932     if(!wszFileName[0])
00933     {
00934         GETTEXTLENGTHEX gt;
00935         gt.flags = GTL_NUMCHARS;
00936         gt.codepage = 1200;
00937         if(!SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0))
00938             return TRUE;
00939     }
00940 
00941     if(!SendMessageW(hEditorWnd, EM_GETMODIFY, 0, 0))
00942     {
00943         return TRUE;
00944     } else
00945     {
00946         LPWSTR displayFileName;
00947         WCHAR *text;
00948         int ret;
00949 
00950         if(!wszFileName[0])
00951             displayFileName = wszDefaultFileName;
00952         else
00953             displayFileName = file_basename(wszFileName);
00954 
00955         text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
00956                          (lstrlenW(displayFileName)+lstrlenW(wszSaveChanges))*sizeof(WCHAR));
00957 
00958         if(!text)
00959             return FALSE;
00960 
00961         wsprintfW(text, wszSaveChanges, displayFileName);
00962 
00963         ret = MessageBoxW(hMainWnd, text, wszAppTitle, MB_YESNOCANCEL | MB_ICONEXCLAMATION);
00964 
00965         HeapFree(GetProcessHeap(), 0, text);
00966 
00967         switch(ret)
00968         {
00969             case IDNO:
00970                 return TRUE;
00971 
00972             case IDYES:
00973                 if(wszFileName[0])
00974                     DoSaveFile(wszFileName, fileFormat);
00975                 else
00976                     DialogSaveFile();
00977                 return TRUE;
00978 
00979             default:
00980                 return FALSE;
00981         }
00982     }
00983 }
00984 
00985 static void DialogOpenFile(void)
00986 {
00987     OPENFILENAMEW ofn;
00988 
00989     WCHAR wszFile[MAX_PATH] = {'\0'};
00990     static const WCHAR wszDefExt[] = {'r','t','f','\0'};
00991 
00992     ZeroMemory(&ofn, sizeof(ofn));
00993 
00994     ofn.lStructSize = sizeof(ofn);
00995     ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ENABLESIZING;
00996     ofn.hwndOwner = hMainWnd;
00997     ofn.lpstrFilter = wszFilter;
00998     ofn.lpstrFile = wszFile;
00999     ofn.nMaxFile = MAX_PATH;
01000     ofn.lpstrDefExt = wszDefExt;
01001     ofn.nFilterIndex = fileformat_number(fileFormat)+1;
01002 
01003     if(GetOpenFileNameW(&ofn))
01004     {
01005         if(prompt_save_changes())
01006             DoOpenFile(ofn.lpstrFile);
01007     }
01008 }
01009 
01010 static void dialog_about(void)
01011 {
01012     HICON icon = LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_WORDPAD), IMAGE_ICON, 48, 48, LR_SHARED);
01013     ShellAboutW(hMainWnd, wszAppTitle, 0, icon);
01014 }
01015 
01016 static INT_PTR CALLBACK formatopts_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
01017 {
01018     switch(message)
01019     {
01020         case WM_INITDIALOG:
01021             {
01022                 LPPROPSHEETPAGEW ps = (LPPROPSHEETPAGEW)lParam;
01023                 int wrap = -1;
01024                 char id[4];
01025                 HWND hIdWnd = GetDlgItem(hWnd, IDC_PAGEFMT_ID);
01026 
01027                 sprintf(id, "%d\n", (int)ps->lParam);
01028                 SetWindowTextA(hIdWnd, id);
01029                 if(wordWrap[ps->lParam] == ID_WORDWRAP_NONE)
01030                     wrap = IDC_PAGEFMT_WN;
01031                 else if(wordWrap[ps->lParam] == ID_WORDWRAP_WINDOW)
01032                     wrap = IDC_PAGEFMT_WW;
01033                 else if(wordWrap[ps->lParam] == ID_WORDWRAP_MARGIN)
01034                     wrap = IDC_PAGEFMT_WM;
01035 
01036                 if(wrap != -1)
01037                     CheckRadioButton(hWnd, IDC_PAGEFMT_WN,
01038                                      IDC_PAGEFMT_WM, wrap);
01039 
01040                 if(barState[ps->lParam] & (1 << BANDID_TOOLBAR))
01041                     CheckDlgButton(hWnd, IDC_PAGEFMT_TB, TRUE);
01042                 if(barState[ps->lParam] & (1 << BANDID_FORMATBAR))
01043                     CheckDlgButton(hWnd, IDC_PAGEFMT_FB, TRUE);
01044                 if(barState[ps->lParam] & (1 << BANDID_RULER))
01045                     CheckDlgButton(hWnd, IDC_PAGEFMT_RU, TRUE);
01046                 if(barState[ps->lParam] & (1 << BANDID_STATUSBAR))
01047                     CheckDlgButton(hWnd, IDC_PAGEFMT_SB, TRUE);
01048             }
01049             break;
01050 
01051         case WM_COMMAND:
01052             switch(LOWORD(wParam))
01053             {
01054                 case IDC_PAGEFMT_WN:
01055                 case IDC_PAGEFMT_WW:
01056                 case IDC_PAGEFMT_WM:
01057                     CheckRadioButton(hWnd, IDC_PAGEFMT_WN, IDC_PAGEFMT_WM,
01058                                      LOWORD(wParam));
01059                     break;
01060 
01061                 case IDC_PAGEFMT_TB:
01062                 case IDC_PAGEFMT_FB:
01063                 case IDC_PAGEFMT_RU:
01064                 case IDC_PAGEFMT_SB:
01065                     CheckDlgButton(hWnd, LOWORD(wParam),
01066                                    !IsDlgButtonChecked(hWnd, LOWORD(wParam)));
01067                     break;
01068             }
01069             break;
01070         case WM_NOTIFY:
01071             {
01072                 LPNMHDR header = (LPNMHDR)lParam;
01073                 if(header->code == PSN_APPLY)
01074                 {
01075                     HWND hIdWnd = GetDlgItem(hWnd, IDC_PAGEFMT_ID);
01076                     char sid[4];
01077                     int id;
01078 
01079                     GetWindowTextA(hIdWnd, sid, 4);
01080                     id = atoi(sid);
01081                     if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_WN))
01082                         wordWrap[id] = ID_WORDWRAP_NONE;
01083                     else if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_WW))
01084                         wordWrap[id] = ID_WORDWRAP_WINDOW;
01085                     else if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_WM))
01086                         wordWrap[id] = ID_WORDWRAP_MARGIN;
01087 
01088                     if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_TB))
01089                         barState[id] |= (1 << BANDID_TOOLBAR);
01090                     else
01091                         barState[id] &= ~(1 << BANDID_TOOLBAR);
01092 
01093                     if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_FB))
01094                         barState[id] |= (1 << BANDID_FORMATBAR);
01095                     else
01096                         barState[id] &= ~(1 << BANDID_FORMATBAR);
01097 
01098                     if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_RU))
01099                         barState[id] |= (1 << BANDID_RULER);
01100                     else
01101                         barState[id] &= ~(1 << BANDID_RULER);
01102 
01103                     if(IsDlgButtonChecked(hWnd, IDC_PAGEFMT_SB))
01104                         barState[id] |= (1 << BANDID_STATUSBAR);
01105                     else
01106                         barState[id] &= ~(1 << BANDID_STATUSBAR);
01107                 }
01108             }
01109             break;
01110     }
01111     return FALSE;
01112 }
01113 
01114 static void dialog_viewproperties(void)
01115 {
01116     PROPSHEETPAGEW psp[2];
01117     PROPSHEETHEADERW psh;
01118     size_t i;
01119     HINSTANCE hInstance = GetModuleHandleW(0);
01120     LPCPROPSHEETPAGEW ppsp = (LPCPROPSHEETPAGEW)&psp;
01121 
01122     psp[0].dwSize = sizeof(PROPSHEETPAGEW);
01123     psp[0].dwFlags = PSP_USETITLE;
01124     U(psp[0]).pszTemplate = MAKEINTRESOURCEW(IDD_FORMATOPTS);
01125     psp[0].pfnDlgProc = formatopts_proc;
01126     psp[0].hInstance = hInstance;
01127     psp[0].lParam = reg_formatindex(SF_TEXT);
01128     psp[0].pfnCallback = NULL;
01129     psp[0].pszTitle = MAKEINTRESOURCEW(STRING_VIEWPROPS_TEXT);
01130     for(i = 1; i < sizeof(psp)/sizeof(psp[0]); i++)
01131     {
01132         psp[i].dwSize = psp[0].dwSize;
01133         psp[i].dwFlags = psp[0].dwFlags;
01134         U(psp[i]).pszTemplate = U(psp[0]).pszTemplate;
01135         psp[i].pfnDlgProc = psp[0].pfnDlgProc;
01136         psp[i].hInstance = psp[0].hInstance;
01137         psp[i].lParam = reg_formatindex(SF_RTF);
01138         psp[i].pfnCallback = psp[0].pfnCallback;
01139         psp[i].pszTitle = MAKEINTRESOURCEW(STRING_VIEWPROPS_RICHTEXT);
01140     }
01141 
01142     psh.dwSize = sizeof(psh);
01143     psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
01144     psh.hwndParent = hMainWnd;
01145     psh.hInstance = hInstance;
01146     psh.pszCaption = MAKEINTRESOURCEW(STRING_VIEWPROPS_TITLE);
01147     psh.nPages = sizeof(psp)/sizeof(psp[0]);
01148     U3(psh).ppsp = ppsp;
01149     U(psh).pszIcon = MAKEINTRESOURCEW(IDI_WORDPAD);
01150 
01151     if(fileFormat & SF_RTF)
01152         U2(psh).nStartPage = 1;
01153     else
01154         U2(psh).nStartPage = 0;
01155     PropertySheetW(&psh);
01156     set_bar_states();
01157     target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
01158 }
01159 
01160 static void HandleCommandLine(LPWSTR cmdline)
01161 {
01162     WCHAR delimiter;
01163     int opt_print = 0;
01164 
01165     /* skip white space */
01166     while (*cmdline == ' ') cmdline++;
01167 
01168     /* skip executable name */
01169     delimiter = (*cmdline == '"' ? '"' : ' ');
01170 
01171     if (*cmdline == delimiter) cmdline++;
01172     while (*cmdline && *cmdline != delimiter) cmdline++;
01173     if (*cmdline == delimiter) cmdline++;
01174 
01175     while (*cmdline)
01176     {
01177         while (isspace(*cmdline)) cmdline++;
01178 
01179         if (*cmdline == '-' || *cmdline == '/')
01180         {
01181             if (!cmdline[2] || isspace(cmdline[2]))
01182             {
01183                 switch (cmdline[1])
01184                 {
01185                 case 'P':
01186                 case 'p':
01187                     opt_print = 1;
01188                     cmdline += 2;
01189                     continue;
01190                 }
01191             }
01192             /* a filename starting by / */
01193         }
01194         break;
01195     }
01196 
01197     if (*cmdline)
01198     {
01199         /* file name is passed on the command line */
01200         if (cmdline[0] == '"')
01201         {
01202             cmdline++;
01203             cmdline[lstrlenW(cmdline) - 1] = 0;
01204         }
01205         DoOpenFile(cmdline);
01206         InvalidateRect(hMainWnd, NULL, FALSE);
01207     }
01208 
01209     if (opt_print)
01210         MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_PRINTING_NOT_IMPLEMENTED), wszAppTitle, MB_OK);
01211 }
01212 
01213 static LRESULT handle_findmsg(LPFINDREPLACEW pFr)
01214 {
01215     if(pFr->Flags & FR_DIALOGTERM)
01216     {
01217         hFindWnd = 0;
01218         pFr->Flags = FR_FINDNEXT;
01219         return 0;
01220     }
01221 
01222     if(pFr->Flags & FR_FINDNEXT || pFr->Flags & FR_REPLACE || pFr->Flags & FR_REPLACEALL)
01223     {
01224         FINDREPLACE_custom *custom_data = (FINDREPLACE_custom*)pFr->lCustData;
01225         DWORD flags;
01226         FINDTEXTEXW ft;
01227         CHARRANGE sel;
01228         LRESULT ret = -1;
01229         HMENU hMenu = GetMenu(hMainWnd);
01230         MENUITEMINFOW mi;
01231 
01232         mi.cbSize = sizeof(mi);
01233         mi.fMask = MIIM_DATA;
01234         mi.dwItemData = 1;
01235         SetMenuItemInfoW(hMenu, ID_FIND_NEXT, FALSE, &mi);
01236 
01237         /* Make sure find field is saved. */
01238         if (pFr->lpstrFindWhat != custom_data->findBuffer)
01239         {
01240             lstrcpynW(custom_data->findBuffer, pFr->lpstrFindWhat,
01241                       sizeof(custom_data->findBuffer));
01242             pFr->lpstrFindWhat = custom_data->findBuffer;
01243         }
01244 
01245         SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&sel.cpMin, (LPARAM)&sel.cpMax);
01246         if(custom_data->endPos == -1) {
01247             custom_data->endPos = sel.cpMin;
01248             custom_data->wrapped = FALSE;
01249         }
01250 
01251         flags = FR_DOWN | (pFr->Flags & (FR_MATCHCASE | FR_WHOLEWORD));
01252         ft.lpstrText = pFr->lpstrFindWhat;
01253 
01254         /* Only replace existing selectino if it is an exact match. */
01255         if (sel.cpMin != sel.cpMax &&
01256             (pFr->Flags & FR_REPLACE || pFr->Flags & FR_REPLACEALL))
01257         {
01258             ft.chrg = sel;
01259             SendMessageW(hEditorWnd, EM_FINDTEXTEXW, flags, (LPARAM)&ft);
01260             if (ft.chrgText.cpMin == sel.cpMin && ft.chrgText.cpMax == sel.cpMax) {
01261                 SendMessageW(hEditorWnd, EM_REPLACESEL, TRUE, (LPARAM)pFr->lpstrReplaceWith);
01262                 SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&sel.cpMin, (LPARAM)&sel.cpMax);
01263             }
01264         }
01265 
01266         /* Search from the start of the selection, but exclude the first character
01267          * from search if there is a selection. */
01268         ft.chrg.cpMin = sel.cpMin;
01269         if (sel.cpMin != sel.cpMax)
01270             ft.chrg.cpMin++;
01271 
01272         /* Search to the end, then wrap around and search from the start. */
01273         if (!custom_data->wrapped) {
01274             ft.chrg.cpMax = -1;
01275             ret = SendMessageW(hEditorWnd, EM_FINDTEXTEXW, flags, (LPARAM)&ft);
01276             if (ret == -1) {
01277                 custom_data->wrapped = TRUE;
01278                 ft.chrg.cpMin = 0;
01279             }
01280         }
01281 
01282         if (ret == -1) {
01283             ft.chrg.cpMax = custom_data->endPos + lstrlenW(pFr->lpstrFindWhat) - 1;
01284             if (ft.chrg.cpMax > ft.chrg.cpMin)
01285                 ret = SendMessageW(hEditorWnd, EM_FINDTEXTEXW, flags, (LPARAM)&ft);
01286         }
01287 
01288         if (ret == -1) {
01289             custom_data->endPos = -1;
01290             EnableWindow(hMainWnd, FALSE);
01291             MessageBoxWithResStringW(hFindWnd, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED),
01292                                      wszAppTitle, MB_OK | MB_ICONASTERISK | MB_TASKMODAL);
01293             EnableWindow(hMainWnd, TRUE);
01294         } else {
01295             SendMessageW(hEditorWnd, EM_SETSEL, ft.chrgText.cpMin, ft.chrgText.cpMax);
01296             SendMessageW(hEditorWnd, EM_SCROLLCARET, 0, 0);
01297 
01298             if (pFr->Flags & FR_REPLACEALL)
01299                 return handle_findmsg(pFr);
01300         }
01301     }
01302 
01303     return 0;
01304 }
01305 
01306 static void dialog_find(LPFINDREPLACEW fr, BOOL replace)
01307 {
01308     static WCHAR selBuffer[128];
01309     static WCHAR replaceBuffer[128];
01310     static FINDREPLACE_custom custom_data;
01311     static const WCHAR endl = '\r';
01312     FINDTEXTW ft;
01313 
01314     /* Allow only one search/replace dialog to open */
01315     if(hFindWnd != NULL)
01316     {
01317         SetActiveWindow(hFindWnd);
01318         return;
01319     }
01320 
01321     ZeroMemory(fr, sizeof(FINDREPLACEW));
01322     fr->lStructSize = sizeof(FINDREPLACEW);
01323     fr->hwndOwner = hMainWnd;
01324     fr->Flags = FR_HIDEUPDOWN;
01325     /* Find field is filled with the selected text if it is non-empty
01326      * and stays within the same paragraph, otherwise the previous
01327      * find field is used. */
01328     SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&ft.chrg.cpMin,
01329                  (LPARAM)&ft.chrg.cpMax);
01330     ft.lpstrText = &endl;
01331     if (ft.chrg.cpMin != ft.chrg.cpMax &&
01332         SendMessageW(hEditorWnd, EM_FINDTEXTW, FR_DOWN, (LPARAM)&ft) == -1)
01333     {
01334         /* Use a temporary buffer for the selected text so that the saved
01335          * find field is only overwritten when a find/replace is clicked. */
01336         GETTEXTEX gt = {sizeof(selBuffer), GT_SELECTION, 1200, NULL, NULL};
01337         SendMessageW(hEditorWnd, EM_GETTEXTEX, (WPARAM)&gt, (LPARAM)selBuffer);
01338         fr->lpstrFindWhat = selBuffer;
01339     } else {
01340         fr->lpstrFindWhat = custom_data.findBuffer;
01341     }
01342     fr->lpstrReplaceWith = replaceBuffer;
01343     custom_data.endPos = -1;
01344     custom_data.wrapped = FALSE;
01345     fr->lCustData = (LPARAM)&custom_data;
01346     fr->wFindWhatLen = sizeof(custom_data.findBuffer);
01347     fr->wReplaceWithLen = sizeof(replaceBuffer);
01348 
01349     if(replace)
01350         hFindWnd = ReplaceTextW(fr);
01351     else
01352         hFindWnd = FindTextW(fr);
01353 }
01354 
01355 static int units_to_twips(UNIT unit, float number)
01356 {
01357     int twips = 0;
01358 
01359     switch(unit)
01360     {
01361     case UNIT_CM:
01362         twips = (int)(number * 1000.0 / (float)CENTMM_PER_INCH * (float)TWIPS_PER_INCH);
01363         break;
01364 
01365     case UNIT_INCH:
01366         twips = (int)(number * (float)TWIPS_PER_INCH);
01367         break;
01368 
01369     case UNIT_PT:
01370         twips = (int)(number * (0.0138 * (float)TWIPS_PER_INCH));
01371         break;
01372     }
01373 
01374     return twips;
01375 }
01376 
01377 static void append_current_units(LPWSTR buffer)
01378 {
01379     static const WCHAR space[] = {' ', 0};
01380     lstrcatW(buffer, space);
01381     lstrcatW(buffer, units_cmW);
01382 }
01383 
01384 static void number_with_units(LPWSTR buffer, int number)
01385 {
01386     static const WCHAR fmt[] = {'%','.','2','f',' ','%','s','\0'};
01387     float converted = (float)number / (float)TWIPS_PER_INCH *(float)CENTMM_PER_INCH / 1000.0;
01388 
01389     sprintfW(buffer, fmt, converted, units_cmW);
01390 }
01391 
01392 static BOOL get_comboexlist_selection(HWND hComboEx, LPWSTR wszBuffer, UINT bufferLength)
01393 {
01394     COMBOBOXEXITEMW cbItem;
01395     COMBOBOXINFO cbInfo;
01396     HWND hCombo, hList;
01397     int idx, result;
01398 
01399     hCombo = (HWND)SendMessage(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
01400     if (!hCombo)
01401         return FALSE;
01402     cbInfo.cbSize = sizeof(COMBOBOXINFO);
01403     result = SendMessage(hCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbInfo);
01404     if (!result)
01405         return FALSE;
01406     hList = cbInfo.hwndList;
01407     idx = SendMessage(hList, LB_GETCURSEL, 0, 0);
01408     if (idx < 0)
01409         return FALSE;
01410 
01411     ZeroMemory(&cbItem, sizeof(cbItem));
01412     cbItem.mask = CBEIF_TEXT;
01413     cbItem.iItem = idx;
01414     cbItem.pszText = wszBuffer;
01415     cbItem.cchTextMax = bufferLength-1;
01416     result = SendMessageW(hComboEx, CBEM_GETITEMW, 0, (LPARAM)&cbItem);
01417 
01418     return result != 0;
01419 }
01420 
01421 static INT_PTR CALLBACK datetime_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
01422 {
01423     switch(message)
01424     {
01425         case WM_INITDIALOG:
01426             {
01427                 WCHAR buffer[MAX_STRING_LEN];
01428                 SYSTEMTIME st;
01429                 HWND hListWnd = GetDlgItem(hWnd, IDC_DATETIME);
01430                 GetLocalTime(&st);
01431 
01432                 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, 0, (LPWSTR)&buffer,
01433                                MAX_STRING_LEN);
01434                 SendMessageW(hListWnd, LB_ADDSTRING, 0, (LPARAM)&buffer);
01435                 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, 0, (LPWSTR)&buffer,
01436                                MAX_STRING_LEN);
01437                 SendMessageW(hListWnd, LB_ADDSTRING, 0, (LPARAM)&buffer);
01438                 GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, 0, (LPWSTR)&buffer, MAX_STRING_LEN);
01439                 SendMessageW(hListWnd, LB_ADDSTRING, 0, (LPARAM)&buffer);
01440 
01441                 SendMessageW(hListWnd, LB_SETSEL, TRUE, 0);
01442             }
01443             break;
01444 
01445         case WM_COMMAND:
01446             switch(LOWORD(wParam))
01447             {
01448                 case IDC_DATETIME:
01449                     if (HIWORD(wParam) != LBN_DBLCLK)
01450                         break;
01451                     /* Fall through */
01452 
01453                 case IDOK:
01454                     {
01455                         LRESULT index;
01456                         HWND hListWnd = GetDlgItem(hWnd, IDC_DATETIME);
01457 
01458                         index = SendMessageW(hListWnd, LB_GETCURSEL, 0, 0);
01459 
01460                         if(index != LB_ERR)
01461                         {
01462                             WCHAR buffer[MAX_STRING_LEN];
01463                             SendMessageW(hListWnd, LB_GETTEXT, index, (LPARAM)&buffer);
01464                             SendMessageW(hEditorWnd, EM_REPLACESEL, TRUE, (LPARAM)&buffer);
01465                         }
01466                     }
01467                     /* Fall through */
01468 
01469                 case IDCANCEL:
01470                     EndDialog(hWnd, wParam);
01471                     return TRUE;
01472             }
01473     }
01474     return FALSE;
01475 }
01476 
01477 static INT_PTR CALLBACK newfile_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
01478 {
01479     switch(message)
01480     {
01481         case WM_INITDIALOG:
01482             {
01483                 HINSTANCE hInstance = GetModuleHandleW(0);
01484                 WCHAR buffer[MAX_STRING_LEN];
01485                 HWND hListWnd = GetDlgItem(hWnd, IDC_NEWFILE);
01486 
01487                 LoadStringW(hInstance, STRING_NEWFILE_RICHTEXT, buffer, MAX_STRING_LEN);
01488                 SendMessageW(hListWnd, LB_ADDSTRING, 0, (LPARAM)&buffer);
01489                 LoadStringW(hInstance, STRING_NEWFILE_TXT, buffer, MAX_STRING_LEN);
01490                 SendMessageW(hListWnd, LB_ADDSTRING, 0, (LPARAM)&buffer);
01491                 LoadStringW(hInstance, STRING_NEWFILE_TXT_UNICODE, buffer, MAX_STRING_LEN);
01492                 SendMessageW(hListWnd, LB_ADDSTRING, 0, (LPARAM)&buffer);
01493 
01494                 SendMessageW(hListWnd, LB_SETSEL, TRUE, 0);
01495             }
01496             break;
01497 
01498         case WM_COMMAND:
01499             switch(LOWORD(wParam))
01500             {
01501                 case IDOK:
01502                     {
01503                         LRESULT index;
01504                         HWND hListWnd = GetDlgItem(hWnd, IDC_NEWFILE);
01505                         index = SendMessageW(hListWnd, LB_GETCURSEL, 0, 0);
01506 
01507                         if(index != LB_ERR)
01508                             EndDialog(hWnd, MAKELONG(fileformat_flags(index),0));
01509                     }
01510                     return TRUE;
01511 
01512                 case IDCANCEL:
01513                     EndDialog(hWnd, MAKELONG(ID_NEWFILE_ABORT,0));
01514                     return TRUE;
01515             }
01516     }
01517     return FALSE;
01518 }
01519 
01520 static INT_PTR CALLBACK paraformat_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
01521 {
01522     static const WORD ALIGNMENT_VALUES[] = {PFA_LEFT, PFA_RIGHT, PFA_CENTER};
01523 
01524     switch(message)
01525     {
01526         case WM_INITDIALOG:
01527             {
01528                 HINSTANCE hInstance = GetModuleHandleW(0);
01529                 WCHAR buffer[MAX_STRING_LEN];
01530                 HWND hListWnd = GetDlgItem(hWnd, IDC_PARA_ALIGN);
01531                 HWND hLeftWnd = GetDlgItem(hWnd, IDC_PARA_LEFT);
01532                 HWND hRightWnd = GetDlgItem(hWnd, IDC_PARA_RIGHT);
01533                 HWND hFirstWnd = GetDlgItem(hWnd, IDC_PARA_FIRST);
01534                 PARAFORMAT2 pf;
01535                 int index = 0;
01536 
01537                 LoadStringW(hInstance, STRING_ALIGN_LEFT, buffer,
01538                             MAX_STRING_LEN);
01539                 SendMessageW(hListWnd, CB_ADDSTRING, 0, (LPARAM)buffer);
01540                 LoadStringW(hInstance, STRING_ALIGN_RIGHT, buffer,
01541                             MAX_STRING_LEN);
01542                 SendMessageW(hListWnd, CB_ADDSTRING, 0, (LPARAM)buffer);
01543                 LoadStringW(hInstance, STRING_ALIGN_CENTER, buffer,
01544                             MAX_STRING_LEN);
01545                 SendMessageW(hListWnd, CB_ADDSTRING, 0, (LPARAM)buffer);
01546 
01547                 pf.cbSize = sizeof(pf);
01548                 pf.dwMask = PFM_ALIGNMENT | PFM_OFFSET | PFM_RIGHTINDENT |
01549                             PFM_STARTINDENT;
01550                 SendMessageW(hEditorWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
01551 
01552                 if(pf.wAlignment == PFA_RIGHT)
01553                     index ++;
01554                 else if(pf.wAlignment == PFA_CENTER)
01555                     index += 2;
01556 
01557                 SendMessageW(hListWnd, CB_SETCURSEL, index, 0);
01558 
01559                 number_with_units(buffer, pf.dxStartIndent + pf.dxOffset);
01560                 SetWindowTextW(hLeftWnd, buffer);
01561                 number_with_units(buffer, pf.dxRightIndent);
01562                 SetWindowTextW(hRightWnd, buffer);
01563                 number_with_units(buffer, -pf.dxOffset);
01564                 SetWindowTextW(hFirstWnd, buffer);
01565             }
01566             break;
01567 
01568         case WM_COMMAND:
01569             switch(LOWORD(wParam))
01570             {
01571                 case IDOK:
01572                     {
01573                         HWND hListWnd = GetDlgItem(hWnd, IDC_PARA_ALIGN);
01574                         HWND hLeftWnd = GetDlgItem(hWnd, IDC_PARA_LEFT);
01575                         HWND hRightWnd = GetDlgItem(hWnd, IDC_PARA_RIGHT);
01576                         HWND hFirstWnd = GetDlgItem(hWnd, IDC_PARA_FIRST);
01577                         WCHAR buffer[MAX_STRING_LEN];
01578                         int index;
01579                         float num;
01580                         int ret = 0;
01581                         PARAFORMAT pf;
01582                         UNIT unit;
01583 
01584                         index = SendMessageW(hListWnd, CB_GETCURSEL, 0, 0);
01585                         pf.wAlignment = ALIGNMENT_VALUES[index];
01586 
01587                         GetWindowTextW(hLeftWnd, buffer, MAX_STRING_LEN);
01588                         if(number_from_string(buffer, &num, &unit))
01589                             ret++;
01590                         pf.dxOffset = units_to_twips(unit, num);
01591                         GetWindowTextW(hRightWnd, buffer, MAX_STRING_LEN);
01592                         if(number_from_string(buffer, &num, &unit))
01593                             ret++;
01594                         pf.dxRightIndent = units_to_twips(unit, num);
01595                         GetWindowTextW(hFirstWnd, buffer, MAX_STRING_LEN);
01596                         if(number_from_string(buffer, &num, &unit))
01597                             ret++;
01598                         pf.dxStartIndent = units_to_twips(unit, num);
01599 
01600                         if(ret != 3)
01601                         {
01602                             MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_INVALID_NUMBER),
01603                                         wszAppTitle, MB_OK | MB_ICONASTERISK);
01604                             return FALSE;
01605                         } else
01606                         {
01607                             if (pf.dxOffset + pf.dxStartIndent < 0
01608                                 && pf.dxStartIndent < 0)
01609                             {
01610                                 /* The first line is before the left edge, so
01611                                  * make sure it is at the left edge. */
01612                                 pf.dxOffset = -pf.dxStartIndent;
01613                             } else if (pf.dxOffset < 0) {
01614                                 /* The second and following lines are before
01615                                  * the left edge, so set it to be at the left
01616                                  * edge, and adjust the first line since it
01617                                  * is relative to it. */
01618                                 pf.dxStartIndent = max(pf.dxStartIndent + pf.dxOffset, 0);
01619                                 pf.dxOffset = 0;
01620                             }
01621                             /* Internally the dxStartIndent is the absolute
01622                              * offset for the first line and dxOffset is
01623                              * to it value as opposed how it is displayed with
01624                              * the first line being the relative value.
01625                              * These two lines make the adjustments. */
01626                             pf.dxStartIndent = pf.dxStartIndent + pf.dxOffset;
01627                             pf.dxOffset = pf.dxOffset - pf.dxStartIndent;
01628 
01629                             pf.cbSize = sizeof(pf);
01630                             pf.dwMask = PFM_ALIGNMENT | PFM_OFFSET | PFM_RIGHTINDENT |
01631                                         PFM_STARTINDENT;
01632                             SendMessageW(hEditorWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
01633                         }
01634                     }
01635                     /* Fall through */
01636 
01637                 case IDCANCEL:
01638                     EndDialog(hWnd, wParam);
01639                     return TRUE;
01640             }
01641     }
01642     return FALSE;
01643 }
01644 
01645 static INT_PTR CALLBACK tabstops_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
01646 {
01647     switch(message)
01648     {
01649         case WM_INITDIALOG:
01650             {
01651                 HWND hTabWnd = GetDlgItem(hWnd, IDC_TABSTOPS);
01652                 PARAFORMAT pf;
01653                 WCHAR buffer[MAX_STRING_LEN];
01654                 int i;
01655 
01656                 pf.cbSize = sizeof(pf);
01657                 pf.dwMask = PFM_TABSTOPS;
01658                 SendMessageW(hEditorWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
01659                 SendMessageW(hTabWnd, CB_LIMITTEXT, MAX_STRING_LEN-1, 0);
01660 
01661                 for(i = 0; i < pf.cTabCount; i++)
01662                 {
01663                     number_with_units(buffer, pf.rgxTabs[i]);
01664                     SendMessageW(hTabWnd, CB_ADDSTRING, 0, (LPARAM)&buffer);
01665                 }
01666                 SetFocus(hTabWnd);
01667             }
01668             break;
01669 
01670         case WM_COMMAND:
01671             switch(LOWORD(wParam))
01672             {
01673                 case IDC_TABSTOPS:
01674                     {
01675                         HWND hTabWnd = (HWND)lParam;
01676                         HWND hAddWnd = GetDlgItem(hWnd, ID_TAB_ADD);
01677                         HWND hDelWnd = GetDlgItem(hWnd, ID_TAB_DEL);
01678                         HWND hEmptyWnd = GetDlgItem(hWnd, ID_TAB_EMPTY);
01679 
01680                         if(GetWindowTextLengthW(hTabWnd))
01681                             EnableWindow(hAddWnd, TRUE);
01682                         else
01683                             EnableWindow(hAddWnd, FALSE);
01684 
01685                         if(SendMessageW(hTabWnd, CB_GETCOUNT, 0, 0))
01686                         {
01687                             EnableWindow(hEmptyWnd, TRUE);
01688 
01689                             if(SendMessageW(hTabWnd, CB_GETCURSEL, 0, 0) == CB_ERR)
01690                                 EnableWindow(hDelWnd, FALSE);
01691                             else
01692                                 EnableWindow(hDelWnd, TRUE);
01693                         } else
01694                         {
01695                             EnableWindow(hEmptyWnd, FALSE);
01696                         }
01697                     }
01698                     break;
01699 
01700                 case ID_TAB_ADD:
01701                     {
01702                         HWND hTabWnd = GetDlgItem(hWnd, IDC_TABSTOPS);
01703                         WCHAR buffer[MAX_STRING_LEN];
01704                         UNIT unit;
01705 
01706                         GetWindowTextW(hTabWnd, buffer, MAX_STRING_LEN);
01707                         append_current_units(buffer);
01708 
01709                         if(SendMessageW(hTabWnd, CB_FINDSTRINGEXACT, -1, (LPARAM)&buffer) == CB_ERR)
01710                         {
01711                             float number = 0;
01712                             int item_count = SendMessage(hTabWnd, CB_GETCOUNT, 0, 0);
01713 
01714                             if(!number_from_string(buffer, &number, &unit))
01715                             {
01716                                 MessageBoxWithResStringW(hWnd, MAKEINTRESOURCEW(STRING_INVALID_NUMBER),
01717                                              wszAppTitle, MB_OK | MB_ICONINFORMATION);
01718                             } else if (item_count >= MAX_TAB_STOPS) {
01719                                 MessageBoxWithResStringW(hWnd, MAKEINTRESOURCEW(STRING_MAX_TAB_STOPS),
01720                                              wszAppTitle, MB_OK | MB_ICONINFORMATION);
01721                             } else {
01722                                 int i;
01723                                 float next_number = -1;
01724                                 int next_number_in_twips = -1;
01725                                 int insert_number = units_to_twips(unit, number);
01726 
01727                                 /* linear search for position to insert the string */
01728                                 for(i = 0; i < item_count; i++)
01729                                 {
01730                                     SendMessageW(hTabWnd, CB_GETLBTEXT, i, (LPARAM)&buffer);
01731                                     number_from_string(buffer, &next_number, &unit);
01732                                     next_number_in_twips = units_to_twips(unit, next_number);
01733                                     if (insert_number <= next_number_in_twips)
01734                                         break;
01735                                 }
01736                                 if (insert_number != next_number_in_twips)
01737                                 {
01738                                     number_with_units(buffer, insert_number);
01739                                     SendMessageW(hTabWnd, CB_INSERTSTRING, i, (LPARAM)&buffer);
01740                                     SetWindowTextW(hTabWnd, 0);
01741                                 }
01742                             }
01743                         }
01744                         SetFocus(hTabWnd);
01745                     }
01746                     break;
01747 
01748                 case ID_TAB_DEL:
01749                     {
01750                         HWND hTabWnd = GetDlgItem(hWnd, IDC_TABSTOPS);
01751                         LRESULT ret;
01752                         ret = SendMessageW(hTabWnd, CB_GETCURSEL, 0, 0);
01753                         if(ret != CB_ERR)
01754                             SendMessageW(hTabWnd, CB_DELETESTRING, ret, 0);
01755                     }
01756                     break;
01757 
01758                 case ID_TAB_EMPTY:
01759                     {
01760                         HWND hTabWnd = GetDlgItem(hWnd, IDC_TABSTOPS);
01761                         SendMessageW(hTabWnd, CB_RESETCONTENT, 0, 0);
01762                         SetFocus(hTabWnd);
01763                     }
01764                     break;
01765 
01766                 case IDOK:
01767                     {
01768                         HWND hTabWnd = GetDlgItem(hWnd, IDC_TABSTOPS);
01769                         int i;
01770                         WCHAR buffer[MAX_STRING_LEN];
01771                         PARAFORMAT pf;
01772                         float number;
01773                         UNIT unit;
01774 
01775                         pf.cbSize = sizeof(pf);
01776                         pf.dwMask = PFM_TABSTOPS;
01777 
01778                         for(i = 0; SendMessageW(hTabWnd, CB_GETLBTEXT, i,
01779                                                 (LPARAM)&buffer) != CB_ERR &&
01780                                                         i < MAX_TAB_STOPS; i++)
01781                         {
01782                             number_from_string(buffer, &number, &unit);
01783                             pf.rgxTabs[i] = units_to_twips(unit, number);
01784                         }
01785                         pf.cTabCount = i;
01786                         SendMessageW(hEditorWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
01787                     }
01788                     /* Fall through */
01789                 case IDCANCEL:
01790                     EndDialog(hWnd, wParam);
01791                     return TRUE;
01792             }
01793     }
01794     return FALSE;
01795 }
01796 
01797 static LRESULT OnCreate( HWND hWnd )
01798 {
01799     HWND hToolBarWnd, hFormatBarWnd,  hReBarWnd, hFontListWnd, hSizeListWnd, hRulerWnd;
01800     HINSTANCE hInstance = GetModuleHandleW(0);
01801     HANDLE hDLL;
01802     TBADDBITMAP ab;
01803     int nStdBitmaps = 0;
01804     REBARINFO rbi;
01805     REBARBANDINFOW rbb;
01806     static const WCHAR wszRichEditDll[] = {'R','I','C','H','E','D','2','0','.','D','L','L','\0'};
01807     static const WCHAR wszRichEditText[] = {'R','i','c','h','E','d','i','t',' ','t','e','x','t','\0'};
01808 
01809     CreateStatusWindowW(CCS_NODIVIDER|WS_CHILD|WS_VISIBLE, wszRichEditText, hWnd, IDC_STATUSBAR);
01810 
01811     hReBarWnd = CreateWindowExW(WS_EX_TOOLWINDOW, REBARCLASSNAMEW, NULL,
01812       CCS_NODIVIDER|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT|CCS_TOP,
01813       CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hWnd, (HMENU)IDC_REBAR, hInstance, NULL);
01814 
01815     rbi.cbSize = sizeof(rbi);
01816     rbi.fMask = 0;
01817     rbi.himl = NULL;
01818     if(!SendMessageW(hReBarWnd, RB_SETBARINFO, 0, (LPARAM)&rbi))
01819         return -1;
01820 
01821     hToolBarWnd = CreateToolbarEx(hReBarWnd, CCS_NOPARENTALIGN|CCS_NOMOVEY|WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS|BTNS_BUTTON,
01822       IDC_TOOLBAR,
01823       1, hInstance, IDB_TOOLBAR,
01824       NULL, 0,
01825       24, 24, 16, 16, sizeof(TBBUTTON));
01826 
01827     ab.hInst = HINST_COMMCTRL;
01828     ab.nID = IDB_STD_SMALL_COLOR;
01829     nStdBitmaps = SendMessageW(hToolBarWnd, TB_ADDBITMAP, 0, (LPARAM)&ab);
01830 
01831     AddButton(hToolBarWnd, nStdBitmaps+STD_FILENEW, ID_FILE_NEW);
01832     AddButton(hToolBarWnd, nStdBitmaps+STD_FILEOPEN, ID_FILE_OPEN);
01833     AddButton(hToolBarWnd, nStdBitmaps+STD_FILESAVE, ID_FILE_SAVE);
01834     AddSeparator(hToolBarWnd);
01835     AddButton(hToolBarWnd, nStdBitmaps+STD_PRINT, ID_PRINT_QUICK);
01836     AddButton(hToolBarWnd, nStdBitmaps+STD_PRINTPRE, ID_PREVIEW);
01837     AddSeparator(hToolBarWnd);
01838     AddButton(hToolBarWnd, nStdBitmaps+STD_FIND, ID_FIND);
01839     AddSeparator(hToolBarWnd);
01840     AddButton(hToolBarWnd, nStdBitmaps+STD_CUT, ID_EDIT_CUT);
01841     AddButton(hToolBarWnd, nStdBitmaps+STD_COPY, ID_EDIT_COPY);
01842     AddButton(hToolBarWnd, nStdBitmaps+STD_PASTE, ID_EDIT_PASTE);
01843     AddButton(hToolBarWnd, nStdBitmaps+STD_UNDO, ID_EDIT_UNDO);
01844     AddButton(hToolBarWnd, nStdBitmaps+STD_REDOW, ID_EDIT_REDO);
01845     AddSeparator(hToolBarWnd);
01846     AddButton(hToolBarWnd, 0, ID_DATETIME);
01847 
01848     SendMessageW(hToolBarWnd, TB_AUTOSIZE, 0, 0);
01849 
01850     rbb.cbSize = REBARBANDINFOW_V6_SIZE;
01851     rbb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_STYLE | RBBIM_ID;
01852     rbb.fStyle = RBBS_CHILDEDGE | RBBS_BREAK | RBBS_NOGRIPPER;
01853     rbb.cx = 0;
01854     rbb.hwndChild = hToolBarWnd;
01855     rbb.cxMinChild = 0;
01856     rbb.cyChild = rbb.cyMinChild = HIWORD(SendMessageW(hToolBarWnd, TB_GETBUTTONSIZE, 0, 0));
01857     rbb.wID = BANDID_TOOLBAR;
01858 
01859     SendMessageW(hReBarWnd, RB_INSERTBAND, -1, (LPARAM)&rbb);
01860 
01861     hFontListWnd = CreateWindowExW(0, WC_COMBOBOXEXW, NULL,
01862                       WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN | CBS_SORT,
01863                       0, 0, 200, 150, hReBarWnd, (HMENU)IDC_FONTLIST, hInstance, NULL);
01864 
01865     rbb.hwndChild = hFontListWnd;
01866     rbb.cx = 200;
01867     rbb.wID = BANDID_FONTLIST;
01868 
01869     SendMessageW(hReBarWnd, RB_INSERTBAND, -1, (LPARAM)&rbb);
01870 
01871     hSizeListWnd = CreateWindowExW(0, WC_COMBOBOXEXW, NULL,
01872                       WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN,
01873                       0, 0, 50, 150, hReBarWnd, (HMENU)IDC_SIZELIST, hInstance, NULL);
01874 
01875     rbb.hwndChild = hSizeListWnd;
01876     rbb.cx = 50;
01877     rbb.fStyle ^= RBBS_BREAK;
01878     rbb.wID = BANDID_SIZELIST;
01879 
01880     SendMessageW(hReBarWnd, RB_INSERTBAND, -1, (LPARAM)&rbb);
01881 
01882     hFormatBarWnd = CreateToolbarEx(hReBarWnd,
01883          CCS_NOPARENTALIGN | CCS_NOMOVEY | WS_VISIBLE | TBSTYLE_TOOLTIPS | BTNS_BUTTON,
01884          IDC_FORMATBAR, 8, hInstance, IDB_FORMATBAR, NULL, 0, 16, 16, 16, 16, sizeof(TBBUTTON));
01885 
01886     AddButton(hFormatBarWnd, 0, ID_FORMAT_BOLD);
01887     AddButton(hFormatBarWnd, 1, ID_FORMAT_ITALIC);
01888     AddButton(hFormatBarWnd, 2, ID_FORMAT_UNDERLINE);
01889     AddButton(hFormatBarWnd, 3, ID_FORMAT_COLOR);
01890     AddSeparator(hFormatBarWnd);
01891     AddButton(hFormatBarWnd, 4, ID_ALIGN_LEFT);
01892     AddButton(hFormatBarWnd, 5, ID_ALIGN_CENTER);
01893     AddButton(hFormatBarWnd, 6, ID_ALIGN_RIGHT);
01894     AddSeparator(hFormatBarWnd);
01895     AddButton(hFormatBarWnd, 7, ID_BULLET);
01896 
01897     SendMessageW(hFormatBarWnd, TB_AUTOSIZE, 0, 0);
01898 
01899     rbb.hwndChild = hFormatBarWnd;
01900     rbb.wID = BANDID_FORMATBAR;
01901 
01902     SendMessageW(hReBarWnd, RB_INSERTBAND, -1, (LPARAM)&rbb);
01903 
01904     hRulerWnd = CreateWindowExW(0, WC_STATICW, NULL, WS_VISIBLE | WS_CHILD,
01905                                 0, 0, 200, 10, hReBarWnd,  (HMENU)IDC_RULER, hInstance, NULL);
01906 
01907 
01908     rbb.hwndChild = hRulerWnd;
01909     rbb.wID = BANDID_RULER;
01910     rbb.fStyle |= RBBS_BREAK;
01911 
01912     SendMessageW(hReBarWnd, RB_INSERTBAND, -1, (LPARAM)&rbb);
01913 
01914     hDLL = LoadLibraryW(wszRichEditDll);
01915     if(!hDLL)
01916     {
01917         MessageBoxWithResStringW(hWnd, MAKEINTRESOURCEW(STRING_LOAD_RICHED_FAILED), wszAppTitle,
01918                     MB_OK | MB_ICONEXCLAMATION);
01919         PostQuitMessage(1);
01920     }
01921 
01922     hEditorWnd = CreateWindowExW(WS_EX_CLIENTEDGE, RICHEDIT_CLASS20W, NULL,
01923       WS_CHILD|WS_VISIBLE|ES_SELECTIONBAR|ES_MULTILINE|ES_AUTOVSCROLL
01924       |ES_WANTRETURN|WS_VSCROLL|ES_NOHIDESEL|WS_HSCROLL,
01925       0, 0, 1000, 100, hWnd, (HMENU)IDC_EDITOR, hInstance, NULL);
01926 
01927     if (!hEditorWnd)
01928     {
01929         fprintf(stderr, "Error code %u\n", GetLastError());
01930         return -1;
01931     }
01932     assert(hEditorWnd);
01933 
01934     setup_richedit_olecallback(hEditorWnd);
01935     SetFocus(hEditorWnd);
01936     SendMessageW(hEditorWnd, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
01937 
01938     set_default_font();
01939 
01940     populate_font_list(hFontListWnd);
01941     populate_size_list(hSizeListWnd);
01942     DoLoadStrings();
01943     SendMessageW(hEditorWnd, EM_SETMODIFY, FALSE, 0);
01944 
01945     ID_FINDMSGSTRING = RegisterWindowMessageW(FINDMSGSTRINGW);
01946 
01947     registry_read_filelist(hWnd);
01948     registry_read_formatopts_all(barState, wordWrap);
01949     registry_read_options();
01950     DragAcceptFiles(hWnd, TRUE);
01951 
01952     return 0;
01953 }
01954 
01955 static LRESULT OnUser( HWND hWnd )
01956 {
01957     HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
01958     HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR);
01959     HWND hwndToolBar = GetDlgItem(hwndReBar, IDC_TOOLBAR);
01960     HWND hwndFormatBar = GetDlgItem(hwndReBar, IDC_FORMATBAR);
01961     int from, to;
01962     CHARFORMAT2W fmt;
01963     PARAFORMAT2 pf;
01964     GETTEXTLENGTHEX gt;
01965 
01966     ZeroMemory(&fmt, sizeof(fmt));
01967     fmt.cbSize = sizeof(fmt);
01968 
01969     ZeroMemory(&pf, sizeof(pf));
01970     pf.cbSize = sizeof(pf);
01971 
01972     gt.flags = GTL_NUMCHARS;
01973     gt.codepage = 1200;
01974 
01975     SendMessageW(hwndToolBar, TB_ENABLEBUTTON, ID_FIND,
01976                  SendMessageW(hwndEditor, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0) ? 1 : 0);
01977 
01978     SendMessageW(hwndEditor, EM_GETCHARFORMAT, TRUE, (LPARAM)&fmt);
01979 
01980     SendMessageW(hwndEditor, EM_GETSEL, (WPARAM)&from, (LPARAM)&to);
01981     SendMessageW(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_UNDO,
01982       SendMessageW(hwndEditor, EM_CANUNDO, 0, 0));
01983     SendMessageW(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_REDO,
01984       SendMessageW(hwndEditor, EM_CANREDO, 0, 0));
01985     SendMessageW(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_CUT, from == to ? 0 : 1);
01986     SendMessageW(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_COPY, from == to ? 0 : 1);
01987 
01988     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_FORMAT_BOLD, (fmt.dwMask & CFM_BOLD) &&
01989             (fmt.dwEffects & CFE_BOLD));
01990     SendMessageW(hwndFormatBar, TB_INDETERMINATE, ID_FORMAT_BOLD, !(fmt.dwMask & CFM_BOLD));
01991     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_FORMAT_ITALIC, (fmt.dwMask & CFM_ITALIC) &&
01992             (fmt.dwEffects & CFE_ITALIC));
01993     SendMessageW(hwndFormatBar, TB_INDETERMINATE, ID_FORMAT_ITALIC, !(fmt.dwMask & CFM_ITALIC));
01994     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_FORMAT_UNDERLINE, (fmt.dwMask & CFM_UNDERLINE) &&
01995             (fmt.dwEffects & CFE_UNDERLINE));
01996     SendMessageW(hwndFormatBar, TB_INDETERMINATE, ID_FORMAT_UNDERLINE, !(fmt.dwMask & CFM_UNDERLINE));
01997 
01998     SendMessageW(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
01999     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_ALIGN_LEFT, (pf.wAlignment == PFA_LEFT));
02000     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_ALIGN_CENTER, (pf.wAlignment == PFA_CENTER));
02001     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_ALIGN_RIGHT, (pf.wAlignment == PFA_RIGHT));
02002 
02003     SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_BULLET, (pf.wNumbering & PFN_BULLET));
02004     return 0;
02005 }
02006 
02007 static LRESULT OnNotify( HWND hWnd, LPARAM lParam)
02008 {
02009     HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
02010     HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR);
02011     NMHDR *pHdr = (NMHDR *)lParam;
02012     HWND hwndFontList = GetDlgItem(hwndReBar, IDC_FONTLIST);
02013     HWND hwndSizeList = GetDlgItem(hwndReBar, IDC_SIZELIST);
02014 
02015     if (pHdr->hwndFrom == hwndFontList || pHdr->hwndFrom == hwndSizeList)
02016     {
02017         if (pHdr->code == CBEN_ENDEDITW)
02018         {
02019             NMCBEENDEDIT *endEdit = (NMCBEENDEDIT *)lParam;
02020             if(pHdr->hwndFrom == hwndFontList)
02021             {
02022                 on_fontlist_modified((LPWSTR)endEdit->szText);
02023             } else if (pHdr->hwndFrom == hwndSizeList)
02024             {
02025                 on_sizelist_modified(hwndFontList,(LPWSTR)endEdit->szText);
02026             }
02027         }
02028         return 0;
02029     }
02030 
02031     if (pHdr->hwndFrom != hwndEditor)
02032         return 0;
02033 
02034     if (pHdr->code == EN_SELCHANGE)
02035     {
02036         SELCHANGE *pSC = (SELCHANGE *)lParam;
02037         char buf[128];
02038 
02039         update_font_list();
02040 
02041         sprintf( buf,"selection = %d..%d, line count=%ld",
02042                  pSC->chrg.cpMin, pSC->chrg.cpMax,
02043                 SendMessage(hwndEditor, EM_GETLINECOUNT, 0, 0));
02044         SetWindowTextA(GetDlgItem(hWnd, IDC_STATUSBAR), buf);
02045         SendMessage(hWnd, WM_USER, 0, 0);
02046         return 1;
02047     }
02048     return 0;
02049 }
02050 
02051 /* Copied from dlls/comdlg32/fontdlg.c */
02052 static const COLORREF textcolors[]=
02053 {
02054     0x00000000L,0x00000080L,0x00008000L,0x00008080L,
02055     0x00800000L,0x00800080L,0x00808000L,0x00808080L,
02056     0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
02057     0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
02058 };
02059 
02060 static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam)
02061 {
02062     HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
02063     static FINDREPLACEW findreplace;
02064 
02065     if ((HWND)lParam == hwndEditor)
02066         return 0;
02067 
02068     switch(LOWORD(wParam))
02069     {
02070 
02071     case ID_FILE_EXIT:
02072         PostMessageW(hWnd, WM_CLOSE, 0, 0);
02073         break;
02074 
02075     case ID_FILE_NEW:
02076         {
02077             HINSTANCE hInstance = GetModuleHandleW(0);
02078             int ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_NEWFILE), hWnd,
02079                                 newfile_proc);
02080 
02081             if(ret != ID_NEWFILE_ABORT)
02082             {
02083                 if(prompt_save_changes())
02084                 {
02085                     SETTEXTEX st;
02086 
02087                     set_caption(NULL);
02088                     wszFileName[0] = '\0';
02089 
02090                     clear_formatting();
02091 
02092                     st.flags = ST_DEFAULT;
02093                     st.codepage = 1200;
02094                     SendMessageW(hEditorWnd, EM_SETTEXTEX, (WPARAM)&st, 0);
02095 
02096                     SendMessageW(hEditorWnd, EM_SETMODIFY, FALSE, 0);
02097                     set_fileformat(ret);
02098                     update_font_list();
02099                 }
02100             }
02101         }
02102         break;
02103 
02104     case ID_FILE_OPEN:
02105         DialogOpenFile();
02106         break;
02107 
02108     case ID_FILE_SAVE:
02109         if(wszFileName[0])
02110         {
02111             DoSaveFile(wszFileName, fileFormat);
02112             break;
02113         }
02114         /* Fall through */
02115 
02116     case ID_FILE_SAVEAS:
02117         DialogSaveFile();
02118         break;
02119 
02120     case ID_FILE_RECENT1:
02121     case ID_FILE_RECENT2:
02122     case ID_FILE_RECENT3:
02123     case ID_FILE_RECENT4:
02124         {
02125             HMENU hMenu = GetMenu(hWnd);
02126             MENUITEMINFOW mi;
02127 
02128             mi.cbSize = sizeof(MENUITEMINFOW);
02129             mi.fMask = MIIM_DATA;
02130             if(GetMenuItemInfoW(hMenu, LOWORD(wParam), FALSE, &mi))
02131                 DoOpenFile((LPWSTR)mi.dwItemData);
02132         }
02133         break;
02134 
02135     case ID_FIND:
02136         dialog_find(&findreplace, FALSE);
02137         break;
02138 
02139     case ID_FIND_NEXT:
02140         handle_findmsg(&findreplace);
02141         break;
02142 
02143     case ID_REPLACE:
02144         dialog_find(&findreplace, TRUE);
02145         break;
02146 
02147     case ID_FONTSETTINGS:
02148         dialog_choose_font();
02149         break;
02150 
02151     case ID_PRINT:
02152         dialog_print(hWnd, wszFileName);
02153         target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
02154         break;
02155 
02156     case ID_PRINT_QUICK:
02157         print_quick(hMainWnd, wszFileName);
02158         target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
02159         break;
02160 
02161     case ID_PREVIEW:
02162         {
02163             int index = reg_formatindex(fileFormat);
02164             DWORD tmp = barState[index];
02165             barState[index] = 1 << BANDID_STATUSBAR;
02166             set_bar_states();
02167             barState[index] = tmp;
02168             ShowWindow(hEditorWnd, FALSE);
02169 
02170             init_preview(hWnd, wszFileName);
02171 
02172             SetMenu(hWnd, NULL);
02173             InvalidateRect(0, 0, TRUE);
02174         }
02175         break;
02176 
02177     case ID_PRINTSETUP:
02178         dialog_printsetup(hWnd);
02179         target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
02180         break;
02181 
02182     case ID_FORMAT_BOLD:
02183     case ID_FORMAT_ITALIC:
02184     case ID_FORMAT_UNDERLINE:
02185         {
02186         CHARFORMAT2W fmt;
02187         int effects = CFE_BOLD;
02188 
02189         ZeroMemory(&fmt, sizeof(fmt));
02190         fmt.cbSize = sizeof(fmt);
02191         SendMessageW(hwndEditor, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
02192 
02193         fmt.dwMask = CFM_BOLD;
02194 
02195         if (LOWORD(wParam) == ID_FORMAT_ITALIC)
02196         {
02197             effects = CFE_ITALIC;
02198             fmt.dwMask = CFM_ITALIC;
02199         } else if (LOWORD(wParam) == ID_FORMAT_UNDERLINE)
02200         {
02201             effects = CFE_UNDERLINE;
02202             fmt.dwMask = CFM_UNDERLINE;
02203         }
02204 
02205         fmt.dwEffects ^= effects;
02206 
02207         SendMessageW(hwndEditor, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
02208         break;
02209         }
02210 
02211     case ID_FORMAT_COLOR:
02212     {
02213         HWND hReBarWnd = GetDlgItem(hWnd, IDC_REBAR);
02214         HWND hFormatBarWnd = GetDlgItem(hReBarWnd, IDC_FORMATBAR);
02215         HMENU hPop;
02216         RECT itemrc;
02217         POINT pt;
02218         int mid;
02219         int itemidx = SendMessage(hFormatBarWnd, TB_COMMANDTOINDEX, ID_FORMAT_COLOR, 0);
02220 
02221         SendMessage(hFormatBarWnd, TB_GETITEMRECT, itemidx, (LPARAM)&itemrc);
02222         pt.x = itemrc.left;
02223         pt.y = itemrc.bottom;
02224         ClientToScreen(hFormatBarWnd, &pt);
02225         hPop = GetSubMenu(hColorPopupMenu, 0);
02226         mid = TrackPopupMenu(hPop, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON |
02227                                    TPM_RETURNCMD | TPM_NONOTIFY,
02228                              pt.x, pt.y, 0, hWnd, 0);
02229         if (mid >= ID_COLOR_FIRST && mid <= ID_COLOR_AUTOMATIC)
02230         {
02231             CHARFORMAT2W fmt;
02232 
02233             ZeroMemory(&fmt, sizeof(fmt));
02234             fmt.cbSize = sizeof(fmt);
02235             SendMessageW(hwndEditor, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
02236 
02237             fmt.dwMask = CFM_COLOR;
02238 
02239             if (mid < ID_COLOR_AUTOMATIC) {
02240                 fmt.crTextColor = textcolors[mid - ID_COLOR_FIRST];
02241                 fmt.dwEffects &= ~CFE_AUTOCOLOR;
02242             } else {
02243                 fmt.dwEffects |= CFE_AUTOCOLOR;
02244             }
02245 
02246             SendMessageW(hwndEditor, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
02247         }
02248         break;
02249     }
02250 
02251     case ID_EDIT_CUT:
02252         PostMessageW(hwndEditor, WM_CUT, 0, 0);
02253         break;
02254 
02255     case ID_EDIT_COPY:
02256         PostMessageW(hwndEditor, WM_COPY, 0, 0);
02257         break;
02258 
02259     case ID_EDIT_PASTE:
02260         PostMessageW(hwndEditor, WM_PASTE, 0, 0);
02261         break;
02262 
02263     case ID_EDIT_CLEAR:
02264         PostMessageW(hwndEditor, WM_CLEAR, 0, 0);
02265         break;
02266 
02267     case ID_EDIT_SELECTALL:
02268         {
02269         CHARRANGE range = {0, -1};
02270         SendMessageW(hwndEditor, EM_EXSETSEL, 0, (LPARAM)&range);
02271         /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
02272         return 0;
02273         }
02274 
02275     case ID_EDIT_GETTEXT:
02276         {
02277         int nLen = GetWindowTextLengthW(hwndEditor);
02278         LPWSTR data = HeapAlloc( GetProcessHeap(), 0, (nLen+1)*sizeof(WCHAR) );
02279         TEXTRANGEW tr;
02280 
02281         GetWindowTextW(hwndEditor, data, nLen+1);
02282         MessageBoxW(NULL, data, wszAppTitle, MB_OK);
02283 
02284         HeapFree( GetProcessHeap(), 0, data);
02285         data = HeapAlloc(GetProcessHeap(), 0, (nLen+1)*sizeof(WCHAR));
02286         tr.chrg.cpMin = 0;
02287         tr.chrg.cpMax = nLen;
02288         tr.lpstrText = data;
02289         SendMessage (hwndEditor, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
02290         MessageBoxW(NULL, data, wszAppTitle, MB_OK);
02291         HeapFree( GetProcessHeap(), 0, data );
02292 
02293         /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
02294         return 0;
02295         }
02296 
02297     case ID_EDIT_CHARFORMAT:
02298     case ID_EDIT_DEFCHARFORMAT:
02299         {
02300         CHARFORMAT2W cf;
02301 
02302         ZeroMemory(&cf, sizeof(cf));
02303         cf.cbSize = sizeof(cf);
02304         cf.dwMask = 0;
02305         SendMessageW(hwndEditor, EM_GETCHARFORMAT,
02306                      LOWORD(wParam) == ID_EDIT_CHARFORMAT, (LPARAM)&cf);
02307         return 0;
02308         }
02309 
02310     case ID_EDIT_PARAFORMAT:
02311         {
02312         PARAFORMAT2 pf;
02313         ZeroMemory(&pf, sizeof(pf));
02314         pf.cbSize = sizeof(pf);
02315         SendMessageW(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
02316         return 0;
02317         }
02318 
02319     case ID_EDIT_SELECTIONINFO:
02320         {
02321         CHARRANGE range = {0, -1};
02322         char buf[128];
02323         WCHAR *data = NULL;
02324 
02325         SendMessage(hwndEditor, EM_EXGETSEL, 0, (LPARAM)&range);
02326         data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * (range.cpMax-range.cpMin+1));
02327         SendMessage(hwndEditor, EM_GETSELTEXT, 0, (LPARAM)data);
02328         sprintf(buf, "Start = %d, End = %d", range.cpMin, range.cpMax);
02329         MessageBoxA(hWnd, buf, "Editor", MB_OK);
02330         MessageBoxW(hWnd, data, wszAppTitle, MB_OK);
02331         HeapFree( GetProcessHeap(), 0, data);
02332         /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
02333         return 0;
02334         }
02335 
02336     case ID_EDIT_READONLY:
02337         {
02338         LONG nStyle = GetWindowLong(hwndEditor, GWL_STYLE);
02339         if (nStyle & ES_READONLY)
02340             SendMessageW(hwndEditor, EM_SETREADONLY, 0, 0);
02341         else
02342             SendMessageW(hwndEditor, EM_SETREADONLY, 1, 0);
02343         return 0;
02344         }
02345 
02346     case ID_EDIT_MODIFIED:
02347         if (SendMessageW(hwndEditor, EM_GETMODIFY, 0, 0))
02348             SendMessageW(hwndEditor, EM_SETMODIFY, 0, 0);
02349         else
02350             SendMessageW(hwndEditor, EM_SETMODIFY, 1, 0);
02351         return 0;
02352 
02353     case ID_EDIT_UNDO:
02354         SendMessageW(hwndEditor, EM_UNDO, 0, 0);
02355         return 0;
02356 
02357     case ID_EDIT_REDO:
02358         SendMessageW(hwndEditor, EM_REDO, 0, 0);
02359         return 0;
02360 
02361     case ID_BULLET:
02362         {
02363             PARAFORMAT pf;
02364 
02365             pf.cbSize = sizeof(pf);
02366             pf.dwMask = PFM_NUMBERING;
02367             SendMessageW(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
02368 
02369             pf.dwMask |=  PFM_OFFSET;
02370 
02371             if(pf.wNumbering == PFN_BULLET)
02372             {
02373                 pf.wNumbering = 0;
02374                 pf.dxOffset = 0;
02375             } else
02376             {
02377                 pf.wNumbering = PFN_BULLET;
02378                 pf.dxOffset = 720;
02379             }
02380 
02381             SendMessageW(hwndEditor, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
02382         }
02383         break;
02384 
02385     case ID_ALIGN_LEFT:
02386     case ID_ALIGN_CENTER:
02387     case ID_ALIGN_RIGHT:
02388         {
02389         PARAFORMAT2 pf;
02390 
02391         pf.cbSize = sizeof(pf);
02392         pf.dwMask = PFM_ALIGNMENT;
02393         switch(LOWORD(wParam)) {
02394         case ID_ALIGN_LEFT: pf.wAlignment = PFA_LEFT; break;
02395         case ID_ALIGN_CENTER: pf.wAlignment = PFA_CENTER; break;
02396         case ID_ALIGN_RIGHT: pf.wAlignment = PFA_RIGHT; break;
02397         }
02398         SendMessageW(hwndEditor, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
02399         break;
02400         }
02401 
02402     case ID_BACK_1:
02403         SendMessageW(hwndEditor, EM_SETBKGNDCOLOR, 1, 0);
02404         break;
02405 
02406     case ID_BACK_2:
02407         SendMessageW(hwndEditor, EM_SETBKGNDCOLOR, 0, RGB(255,255,192));
02408         break;
02409 
02410     case ID_TOGGLE_TOOLBAR:
02411         set_toolbar_state(BANDID_TOOLBAR, !is_bar_visible(BANDID_TOOLBAR));
02412         update_window();
02413         break;
02414 
02415     case ID_TOGGLE_FORMATBAR:
02416         set_toolbar_state(BANDID_FONTLIST, !is_bar_visible(BANDID_FORMATBAR));
02417         set_toolbar_state(BANDID_SIZELIST, !is_bar_visible(BANDID_FORMATBAR));
02418         set_toolbar_state(BANDID_FORMATBAR, !is_bar_visible(BANDID_FORMATBAR));
02419         update_window();
02420         break;
02421 
02422     case ID_TOGGLE_STATUSBAR:
02423         set_statusbar_state(!is_bar_visible(BANDID_STATUSBAR));
02424         update_window();
02425         break;
02426 
02427     case ID_TOGGLE_RULER:
02428         set_toolbar_state(BANDID_RULER, !is_bar_visible(BANDID_RULER));
02429         update_window();
02430         break;
02431 
02432     case ID_DATETIME:
02433         DialogBoxW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_DATETIME), hWnd, datetime_proc);
02434         break;
02435 
02436     case ID_PARAFORMAT:
02437         DialogBoxW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_PARAFORMAT), hWnd, paraformat_proc);
02438         break;
02439 
02440     case ID_TABSTOPS:
02441         DialogBoxW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_TABSTOPS), hWnd, tabstops_proc);
02442         break;
02443 
02444     case ID_ABOUT:
02445         dialog_about();
02446         break;
02447 
02448     case ID_VIEWPROPERTIES:
02449         dialog_viewproperties();
02450         break;
02451 
02452     case IDC_FONTLIST:
02453         if (HIWORD(wParam) == CBN_SELENDOK)
02454         {
02455             WCHAR buffer[LF_FACESIZE];
02456             HWND hwndFontList = (HWND)lParam;
02457             get_comboexlist_selection(hwndFontList, buffer, LF_FACESIZE);
02458             on_fontlist_modified(buffer);
02459         }
02460         break;
02461 
02462     case IDC_SIZELIST:
02463         if (HIWORD(wParam) == CBN_SELENDOK)
02464         {
02465             WCHAR buffer[MAX_STRING_LEN+1];
02466             HWND hwndSizeList = (HWND)lParam;
02467             get_comboexlist_selection(hwndSizeList, buffer, MAX_STRING_LEN+1);
02468             on_sizelist_modified(hwndSizeList, buffer);
02469         }
02470         break;
02471 
02472     default:
02473         SendMessageW(hwndEditor, WM_COMMAND, wParam, lParam);
02474         break;
02475     }
02476     return 0;
02477 }
02478 
02479 static LRESULT OnInitPopupMenu( HWND hWnd, WPARAM wParam )
02480 {
02481     HMENU hMenu = (HMENU)wParam;
02482     HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
02483     HWND hwndStatus = GetDlgItem(hWnd, IDC_STATUSBAR);
02484     PARAFORMAT pf;
02485     int nAlignment = -1;
02486     int selFrom, selTo;
02487     GETTEXTLENGTHEX gt;
02488     LRESULT textLength;
02489     MENUITEMINFOW mi;
02490 
02491     SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&selFrom, (LPARAM)&selTo);
02492     EnableMenuItem(hMenu, ID_EDIT_COPY, MF_BYCOMMAND|(selFrom == selTo) ? MF_GRAYED : MF_ENABLED);
02493     EnableMenuItem(hMenu, ID_EDIT_CUT, MF_BYCOMMAND|(selFrom == selTo) ? MF_GRAYED : MF_ENABLED);
02494 
02495     pf.cbSize = sizeof(PARAFORMAT);
02496     SendMessageW(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
02497     CheckMenuItem(hMenu, ID_EDIT_READONLY,
02498       MF_BYCOMMAND|(GetWindowLong(hwndEditor, GWL_STYLE)&ES_READONLY ? MF_CHECKED : MF_UNCHECKED));
02499     CheckMenuItem(hMenu, ID_EDIT_MODIFIED,
02500       MF_BYCOMMAND|(SendMessage(hwndEditor, EM_GETMODIFY, 0, 0) ? MF_CHECKED : MF_UNCHECKED));
02501     if (pf.dwMask & PFM_ALIGNMENT)
02502         nAlignment = pf.wAlignment;
02503     CheckMenuItem(hMenu, ID_ALIGN_LEFT, MF_BYCOMMAND|(nAlignment == PFA_LEFT) ?
02504             MF_CHECKED : MF_UNCHECKED);
02505     CheckMenuItem(hMenu, ID_ALIGN_CENTER, MF_BYCOMMAND|(nAlignment == PFA_CENTER) ?
02506             MF_CHECKED : MF_UNCHECKED);
02507     CheckMenuItem(hMenu, ID_ALIGN_RIGHT, MF_BYCOMMAND|(nAlignment == PFA_RIGHT) ?
02508             MF_CHECKED : MF_UNCHECKED);
02509     CheckMenuItem(hMenu, ID_BULLET, MF_BYCOMMAND | ((pf.wNumbering == PFN_BULLET) ?
02510             MF_CHECKED : MF_UNCHECKED));
02511     EnableMenuItem(hMenu, ID_EDIT_UNDO, MF_BYCOMMAND|(SendMessageW(hwndEditor, EM_CANUNDO, 0, 0)) ?
02512             MF_ENABLED : MF_GRAYED);
02513     EnableMenuItem(hMenu, ID_EDIT_REDO, MF_BYCOMMAND|(SendMessageW(hwndEditor, EM_CANREDO, 0, 0)) ?
02514             MF_ENABLED : MF_GRAYED);
02515 
02516     CheckMenuItem(hMenu, ID_TOGGLE_TOOLBAR, MF_BYCOMMAND|(is_bar_visible(BANDID_TOOLBAR)) ?
02517             MF_CHECKED : MF_UNCHECKED);
02518 
02519     CheckMenuItem(hMenu, ID_TOGGLE_FORMATBAR, MF_BYCOMMAND|(is_bar_visible(BANDID_FORMATBAR)) ?
02520             MF_CHECKED : MF_UNCHECKED);
02521 
02522     CheckMenuItem(hMenu, ID_TOGGLE_STATUSBAR, MF_BYCOMMAND|IsWindowVisible(hwndStatus) ?
02523             MF_CHECKED : MF_UNCHECKED);
02524 
02525     CheckMenuItem(hMenu, ID_TOGGLE_RULER, MF_BYCOMMAND|(is_bar_visible(BANDID_RULER)) ? MF_CHECKED : MF_UNCHECKED);
02526 
02527     gt.flags = GTL_NUMCHARS;
02528     gt.codepage = 1200;
02529     textLength = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
02530     EnableMenuItem(hMenu, ID_FIND, MF_BYCOMMAND|(textLength ? MF_ENABLED : MF_GRAYED));
02531 
02532     mi.cbSize = sizeof(mi);
02533     mi.fMask = MIIM_DATA;
02534 
02535     GetMenuItemInfoW(hMenu, ID_FIND_NEXT, FALSE, &mi);
02536 
02537     EnableMenuItem(hMenu, ID_FIND_NEXT, MF_BYCOMMAND|((textLength && mi.dwItemData) ?
02538                    MF_ENABLED : MF_GRAYED));
02539 
02540     EnableMenuItem(hMenu, ID_REPLACE, MF_BYCOMMAND|(textLength ? MF_ENABLED : MF_GRAYED));
02541 
02542     return 0;
02543 }
02544 
02545 static LRESULT OnSize( HWND hWnd, WPARAM wParam, LPARAM lParam )
02546 {
02547     int nStatusSize = 0;
02548     RECT rc;
02549     HWND hwndEditor = preview_isactive() ? GetDlgItem(hWnd, IDC_PREVIEW) : GetDlgItem(hWnd, IDC_EDITOR);
02550     HWND hwndStatusBar = GetDlgItem(hWnd, IDC_STATUSBAR);
02551     HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR);
02552     HWND hRulerWnd = GetDlgItem(hwndReBar, IDC_RULER);
02553     int rebarHeight = 0;
02554 
02555     if (hwndStatusBar)
02556     {
02557         SendMessageW(hwndStatusBar, WM_SIZE, 0, 0);
02558         if (IsWindowVisible(hwndStatusBar))
02559         {
02560             GetClientRect(hwndStatusBar, &rc);
02561             nStatusSize = rc.bottom - rc.top;
02562         } else
02563         {
02564             nStatusSize = 0;
02565         }
02566     }
02567     if (hwndReBar)
02568     {
02569         rebarHeight = SendMessageW(hwndReBar, RB_GETBARHEIGHT, 0, 0);
02570 
02571         MoveWindow(hwndReBar, 0, 0, LOWORD(lParam), rebarHeight, TRUE);
02572     }
02573     if (hwndEditor)
02574     {
02575         GetClientRect(hWnd, &rc);
02576         MoveWindow(hwndEditor, 0, rebarHeight, rc.right, rc.bottom-nStatusSize-rebarHeight, TRUE);
02577     }
02578 
02579     redraw_ruler(hRulerWnd);
02580 
02581     return DefWindowProcW(hWnd, WM_SIZE, wParam, lParam);
02582 }
02583 
02584 static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
02585 {
02586     if(msg == ID_FINDMSGSTRING)
02587         return handle_findmsg((LPFINDREPLACEW)lParam);
02588 
02589     switch(msg)
02590     {
02591     case WM_CREATE:
02592         return OnCreate( hWnd );
02593 
02594     case WM_USER:
02595         return OnUser( hWnd );
02596 
02597     case WM_NOTIFY:
02598         return OnNotify( hWnd, lParam );
02599 
02600     case WM_COMMAND:
02601         if(preview_isactive())
02602         {
02603             return preview_command( hWnd, wParam );
02604         }
02605 
02606         return OnCommand( hWnd, wParam, lParam );
02607 
02608     case WM_DESTROY:
02609         PostQuitMessage(0);
02610         break;
02611 
02612     case WM_CLOSE:
02613         if(preview_isactive())
02614         {
02615             preview_exit(hWnd);
02616         } else if(prompt_save_changes())
02617         {
02618             registry_set_options(hMainWnd);
02619             registry_set_formatopts_all(barState, wordWrap);
02620             PostQuitMessage(0);
02621         }
02622         break;
02623 
02624     case WM_ACTIVATE:
02625         if (LOWORD(wParam))
02626             SetFocus(GetDlgItem(hWnd, IDC_EDITOR));
02627         return 0;
02628 
02629     case WM_INITMENUPOPUP:
02630         return OnInitPopupMenu( hWnd, wParam );
02631 
02632     case WM_SIZE:
02633         return OnSize( hWnd, wParam, lParam );
02634 
02635     case WM_CONTEXTMENU:
02636         return DefWindowProcW(hWnd, msg, wParam, lParam);
02637 
02638     case WM_DROPFILES:
02639         {
02640             WCHAR file[MAX_PATH];
02641             DragQueryFileW((HDROP)wParam, 0, file, MAX_PATH);
02642             DragFinish((HDROP)wParam);
02643 
02644             if(prompt_save_changes())
02645                 DoOpenFile(file);
02646         }
02647         break;
02648     case WM_PAINT:
02649         if(!preview_isactive())
02650             return DefWindowProcW(hWnd, msg, wParam, lParam);
02651 
02652     default:
02653         return DefWindowProcW(hWnd, msg, wParam, lParam);
02654     }
02655 
02656     return 0;
02657 }
02658 
02659 int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hOldInstance, LPSTR szCmdParagraph, int nCmdShow)
02660 {
02661     INITCOMMONCONTROLSEX classes = {8, ICC_BAR_CLASSES|ICC_COOL_CLASSES|ICC_USEREX_CLASSES};
02662     HACCEL hAccel;
02663     WNDCLASSEXW wc;
02664     MSG msg;
02665     RECT rc;
02666     UINT_PTR hPrevRulerProc;
02667     HWND hRulerWnd;
02668     POINTL EditPoint;
02669     DWORD bMaximized;
02670     static const WCHAR wszAccelTable[] = {'M','A','I','N','A','C','C','E','L',
02671                                           'T','A','B','L','E','\0'};
02672 
02673     InitCommonControlsEx(&classes);
02674 
02675     hAccel = LoadAcceleratorsW(hInstance, wszAccelTable);
02676 
02677     wc.cbSize = sizeof(wc);
02678     wc.style = 0;
02679     wc.lpfnWndProc = WndProc;
02680     wc.cbClsExtra = 0;
02681     wc.cbWndExtra = 4;
02682     wc.hInstance = hInstance;
02683     wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_WORDPAD));
02684     wc.hIconSm = LoadImageW(hInstance, MAKEINTRESOURCEW(IDI_WORDPAD), IMAGE_ICON,
02685                             GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
02686     wc.hCursor = LoadCursor(NULL, IDC_IBEAM);
02687     wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
02688     wc.lpszMenuName = MAKEINTRESOURCEW(IDM_MAINMENU);
02689     wc.lpszClassName = wszMainWndClass;
02690     RegisterClassExW(&wc);
02691 
02692     wc.style = 0;
02693     wc.lpfnWndProc = preview_proc;
02694     wc.cbClsExtra = 0;
02695     wc.cbWndExtra = 0;
02696     wc.hInstance = hInstance;
02697     wc.hIcon = NULL;
02698     wc.hIconSm = NULL;
02699     wc.hCursor = LoadCursor(NULL, IDC_IBEAM);
02700     wc.hbrBackground = NULL;
02701     wc.lpszMenuName = NULL;
02702     wc.lpszClassName = wszPreviewWndClass;
02703     RegisterClassExW(&wc);
02704 
02705     registry_read_winrect(&rc);
02706     hMainWnd = CreateWindowExW(0, wszMainWndClass, wszAppTitle, WS_CLIPCHILDREN|WS_OVERLAPPEDWINDOW,
02707       rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInstance, NULL);
02708     registry_read_maximized(&bMaximized);
02709     if ((nCmdShow == SW_SHOWNORMAL || nCmdShow == SW_SHOWDEFAULT)
02710          && bMaximized)
02711         nCmdShow = SW_SHOWMAXIMIZED;
02712     ShowWindow(hMainWnd, nCmdShow);
02713 
02714     set_caption(NULL);
02715     set_bar_states();
02716     set_fileformat(SF_RTF);
02717     hColorPopupMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_COLOR_POPUP));
02718     get_default_printer_opts();
02719     target_device(hMainWnd, wordWrap[reg_formatindex(fileFormat)]);
02720 
02721     hRulerWnd = GetDlgItem(GetDlgItem(hMainWnd, IDC_REBAR), IDC_RULER);
02722     SendMessageW(GetDlgItem(hMainWnd, IDC_EDITOR), EM_POSFROMCHAR, (WPARAM)&EditPoint, 0);
02723     hPrevRulerProc = SetWindowLongPtrW(hRulerWnd, GWLP_WNDPROC, (UINT_PTR)ruler_proc);
02724     SendMessageW(hRulerWnd, WM_USER, (WPARAM)&EditPoint, hPrevRulerProc);
02725 
02726     HandleCommandLine(GetCommandLineW());
02727 
02728     while(GetMessageW(&msg,0,0,0))
02729     {
02730         if (IsDialogMessage(hFindWnd, &msg))
02731             continue;
02732 
02733         if (TranslateAcceleratorW(hMainWnd, hAccel, &msg))
02734             continue;
02735         TranslateMessage(&msg);
02736         DispatchMessageW(&msg);
02737         if (!PeekMessageW(&msg, 0, 0, 0, PM_NOREMOVE))
02738             SendMessageW(hMainWnd, WM_USER, 0, 0);
02739     }
02740 
02741     return 0;
02742 }

Generated on Fri May 25 2012 04:15:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.