2 * Wordpad implementation
4 * Copyright 2004 by Krzysztof Foltman
5 * Copyright 2007-2008 by Alexander N. Sørnes <alex@thehandofagony.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define WIN32_LEAN_AND_MEAN
41 static const WCHAR wszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
43 static const WCHAR wszMainWndClass
[] = {'W','O','R','D','P','A','D','T','O','P',0};
45 static const WCHAR stringFormat
[] = {'%','2','d','\0'};
47 const WCHAR wszPreviewWndClass
[] = {'P','r','t','P','r','e','v','i','e','w',0};
48 LRESULT CALLBACK
preview_proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
51 static HWND hEditorWnd
;
53 static HMENU hColorPopupMenu
;
55 static UINT ID_FINDMSGSTRING
;
57 static DWORD wordWrap
[2];
58 static DWORD barState
[2];
59 static WPARAM fileFormat
= SF_RTF
;
61 static WCHAR wszFileName
[MAX_PATH
];
62 static WCHAR wszFilter
[MAX_STRING_LEN
*4+6*3+5];
63 static WCHAR wszDefaultFileName
[MAX_STRING_LEN
];
64 static WCHAR wszSaveChanges
[MAX_STRING_LEN
];
65 static WCHAR units_cmW
[MAX_STRING_LEN
];
66 static WCHAR units_inW
[MAX_STRING_LEN
];
67 static WCHAR units_inchW
[MAX_STRING_LEN
];
68 static WCHAR units_ptW
[MAX_STRING_LEN
];
70 static int last_bullet
= PFN_BULLET
;
72 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
85 WCHAR findBuffer
[128];
88 /* Load string resources */
89 static void DoLoadStrings(void)
92 static const WCHAR files_rtf
[] = {'*','.','r','t','f','\0'};
93 static const WCHAR files_txt
[] = {'*','.','t','x','t','\0'};
94 static const WCHAR files_all
[] = {'*','.','*','\0'};
96 HINSTANCE hInstance
= GetModuleHandleW(0);
98 p
+= 1 + LoadStringW(hInstance
, STRING_RICHTEXT_FILES_RTF
, p
, MAX_STRING_LEN
);
99 lstrcpyW(p
, files_rtf
);
100 p
+= lstrlenW(p
) + 1;
101 p
+= 1 + LoadStringW(hInstance
, STRING_TEXT_FILES_TXT
, p
, MAX_STRING_LEN
);
102 lstrcpyW(p
, files_txt
);
103 p
+= lstrlenW(p
) + 1;
104 p
+= 1 + LoadStringW(hInstance
, STRING_TEXT_FILES_UNICODE_TXT
, p
, MAX_STRING_LEN
);
105 lstrcpyW(p
, files_txt
);
106 p
+= lstrlenW(p
) + 1;
107 p
+= 1 + LoadStringW(hInstance
, STRING_ALL_FILES
, p
, MAX_STRING_LEN
);
108 lstrcpyW(p
, files_all
);
109 p
+= lstrlenW(p
) + 1;
112 p
= wszDefaultFileName
;
113 LoadStringW(hInstance
, STRING_DEFAULT_FILENAME
, p
, MAX_STRING_LEN
);
116 LoadStringW(hInstance
, STRING_PROMPT_SAVE_CHANGES
, p
, MAX_STRING_LEN
);
118 LoadStringW(hInstance
, STRING_UNITS_CM
, units_cmW
, MAX_STRING_LEN
);
119 LoadStringW(hInstance
, STRING_UNITS_IN
, units_inW
, MAX_STRING_LEN
);
120 LoadStringW(hInstance
, STRING_UNITS_INCH
, units_inchW
, MAX_STRING_LEN
);
121 LoadStringW(hInstance
, STRING_UNITS_PT
, units_ptW
, MAX_STRING_LEN
);
124 /* Show a message box with resource strings */
125 static int MessageBoxWithResStringW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
)
127 MSGBOXPARAMSW params
;
129 params
.cbSize
= sizeof(params
);
130 params
.hwndOwner
= hWnd
;
131 params
.hInstance
= GetModuleHandleW(0);
132 params
.lpszText
= lpText
;
133 params
.lpszCaption
= lpCaption
;
134 params
.dwStyle
= uType
;
135 params
.lpszIcon
= NULL
;
136 params
.dwContextHelpId
= 0;
137 params
.lpfnMsgBoxCallback
= NULL
;
138 params
.dwLanguageId
= 0;
139 return MessageBoxIndirectW(¶ms
);
143 static void AddButtonStyle(HWND hwndToolBar
, int nImage
, int nCommand
, BYTE style
)
147 ZeroMemory(&button
, sizeof(button
));
148 button
.iBitmap
= nImage
;
149 button
.idCommand
= nCommand
;
150 button
.fsState
= TBSTATE_ENABLED
;
151 button
.fsStyle
= style
;
154 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
157 static void AddButton(HWND hwndToolBar
, int nImage
, int nCommand
)
159 AddButtonStyle(hwndToolBar
, nImage
, nCommand
, BTNS_BUTTON
);
162 static void AddSeparator(HWND hwndToolBar
)
166 ZeroMemory(&button
, sizeof(button
));
168 button
.idCommand
= 0;
170 button
.fsStyle
= BTNS_SEP
;
173 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
176 static DWORD CALLBACK
stream_in(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
178 HANDLE hFile
= (HANDLE
)cookie
;
181 if(!ReadFile(hFile
, buffer
, cb
, &read
, 0))
189 static DWORD CALLBACK
stream_out(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
193 HANDLE hFile
= (HANDLE
)cookie
;
195 ret
= WriteFile(hFile
, buffer
, cb
, &written
, 0);
197 if(!ret
|| (cb
!= written
))
205 LPWSTR
file_basename(LPWSTR path
)
207 LPWSTR pos
= path
+ lstrlenW(path
);
211 if(*pos
== '\\' || *pos
== '/')
221 static void set_caption(LPCWSTR wszNewFileName
)
223 static const WCHAR wszSeparator
[] = {' ','-',' '};
228 wszNewFileName
= wszDefaultFileName
;
230 wszNewFileName
= file_basename((LPWSTR
)wszNewFileName
);
232 wszCaption
= calloc(1, lstrlenW(wszNewFileName
)*sizeof(WCHAR
)+sizeof(wszSeparator
)+sizeof(wszAppTitle
));
237 memcpy(wszCaption
, wszNewFileName
, lstrlenW(wszNewFileName
)*sizeof(WCHAR
));
238 length
+= lstrlenW(wszNewFileName
);
239 memcpy(wszCaption
+ length
, wszSeparator
, sizeof(wszSeparator
));
240 length
+= ARRAY_SIZE(wszSeparator
);
241 memcpy(wszCaption
+ length
, wszAppTitle
, sizeof(wszAppTitle
));
243 SetWindowTextW(hMainWnd
, wszCaption
);
248 static BOOL
validate_endptr(LPCWSTR endptr
, UNIT
*punit
)
257 while(*endptr
== ' ')
261 return *endptr
== '\0';
263 if(!lstrcmpW(endptr
, units_cmW
))
266 endptr
+= lstrlenW(units_cmW
);
268 else if (!lstrcmpW(endptr
, units_inW
))
271 endptr
+= lstrlenW(units_inW
);
273 else if (!lstrcmpW(endptr
, units_inchW
))
276 endptr
+= lstrlenW(units_inchW
);
278 else if (!lstrcmpW(endptr
, units_ptW
))
281 endptr
+= lstrlenW(units_ptW
);
284 return *endptr
== '\0';
287 static BOOL
number_from_string(LPCWSTR string
, float *num
, UNIT
*punit
)
294 ret
= wcstod(string
, &endptr
);
298 if((ret
== 0 && errno
!= 0) || endptr
== string
|| !validate_endptr(endptr
, punit
))
308 static void set_size(float size
)
312 ZeroMemory(&fmt
, sizeof(fmt
));
313 fmt
.cbSize
= sizeof(fmt
);
314 fmt
.dwMask
= CFM_SIZE
;
315 fmt
.yHeight
= (int)(size
* 20.0);
316 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
319 static void on_sizelist_modified(HWND hwndSizeList
, LPWSTR wszNewFontSize
)
321 WCHAR sizeBuffer
[MAX_STRING_LEN
];
324 ZeroMemory(&format
, sizeof(format
));
325 format
.cbSize
= sizeof(format
);
326 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);
328 wsprintfW(sizeBuffer
, stringFormat
, format
.yHeight
/ 20);
329 if(lstrcmpW(sizeBuffer
, wszNewFontSize
))
332 if(number_from_string(wszNewFontSize
, &size
, NULL
)
338 SetWindowTextW(hwndSizeList
, sizeBuffer
);
339 MessageBoxWithResStringW(hMainWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
340 wszAppTitle
, MB_OK
| MB_ICONINFORMATION
);
345 static void add_size(HWND hSizeListWnd
, unsigned size
)
348 COMBOBOXEXITEMW cbItem
;
349 cbItem
.mask
= CBEIF_TEXT
;
352 wsprintfW(buffer
, stringFormat
, size
);
353 cbItem
.pszText
= buffer
;
354 SendMessageW(hSizeListWnd
, CBEM_INSERTITEMW
, 0, (LPARAM
)&cbItem
);
357 static void populate_size_list(HWND hSizeListWnd
)
359 HWND hReBarWnd
= GetDlgItem(hMainWnd
, IDC_REBAR
);
360 HWND hFontListWnd
= GetDlgItem(hReBarWnd
, IDC_FONTLIST
);
361 COMBOBOXEXITEMW cbFontItem
;
363 HWND hListEditWnd
= (HWND
)SendMessageW(hSizeListWnd
, CBEM_GETEDITCONTROL
, 0, 0);
364 HDC hdc
= GetDC(hMainWnd
);
365 static const unsigned choices
[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
370 ZeroMemory(&fmt
, sizeof(fmt
));
371 fmt
.cbSize
= sizeof(fmt
);
372 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
374 cbFontItem
.mask
= CBEIF_LPARAM
;
375 cbFontItem
.iItem
= SendMessageW(hFontListWnd
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)fmt
.szFaceName
);
376 SendMessageW(hFontListWnd
, CBEM_GETITEMW
, 0, (LPARAM
)&cbFontItem
);
378 fontStyle
= (DWORD
)LOWORD(cbFontItem
.lParam
);
380 SendMessageW(hSizeListWnd
, CB_RESETCONTENT
, 0, 0);
382 if((fontStyle
& RASTER_FONTTYPE
) && cbFontItem
.iItem
)
384 add_size(hSizeListWnd
, (BYTE
)MulDiv(HIWORD(cbFontItem
.lParam
), 72,
385 GetDeviceCaps(hdc
, LOGPIXELSY
)));
388 for(i
= 0; i
< ARRAY_SIZE(choices
); i
++)
389 add_size(hSizeListWnd
, choices
[i
]);
392 wsprintfW(buffer
, stringFormat
, fmt
.yHeight
/ 20);
393 SendMessageW(hListEditWnd
, WM_SETTEXT
, 0, (LPARAM
)buffer
);
396 static void update_size_list(void)
398 HWND hReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
399 HWND hwndSizeList
= GetDlgItem(hReBar
, IDC_SIZELIST
);
400 HWND hwndSizeListEdit
= (HWND
)SendMessageW(hwndSizeList
, CBEM_GETEDITCONTROL
, 0, 0);
401 WCHAR fontSize
[MAX_STRING_LEN
], sizeBuffer
[MAX_STRING_LEN
];
404 ZeroMemory(&fmt
, sizeof(fmt
));
405 fmt
.cbSize
= sizeof(fmt
);
407 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
409 SendMessageW(hwndSizeListEdit
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)fontSize
);
410 wsprintfW(sizeBuffer
, stringFormat
, fmt
.yHeight
/ 20);
412 if(lstrcmpW(fontSize
, sizeBuffer
))
413 SendMessageW(hwndSizeListEdit
, WM_SETTEXT
, 0, (LPARAM
)sizeBuffer
);
416 static void update_font_list(void)
418 HWND hReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
419 HWND hFontList
= GetDlgItem(hReBar
, IDC_FONTLIST
);
420 HWND hFontListEdit
= (HWND
)SendMessageW(hFontList
, CBEM_GETEDITCONTROL
, 0, 0);
421 WCHAR fontName
[MAX_STRING_LEN
];
424 ZeroMemory(&fmt
, sizeof(fmt
));
425 fmt
.cbSize
= sizeof(fmt
);
427 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
428 if (!SendMessageW(hFontListEdit
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)fontName
)) return;
430 if(lstrcmpW(fontName
, fmt
.szFaceName
))
432 SendMessageW(hFontListEdit
, WM_SETTEXT
, 0, (LPARAM
)fmt
.szFaceName
);
433 populate_size_list(GetDlgItem(hReBar
, IDC_SIZELIST
));
440 static void clear_formatting(void)
444 pf
.cbSize
= sizeof(pf
);
445 pf
.dwMask
= PFM_ALIGNMENT
;
446 pf
.wAlignment
= PFA_LEFT
;
447 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
450 static int fileformat_number(WPARAM format
)
454 if(format
== SF_TEXT
)
457 } else if (format
== (SF_TEXT
| SF_UNICODE
))
464 static WPARAM
fileformat_flags(int format
)
466 WPARAM flags
[] = { SF_RTF
, SF_TEXT
, SF_TEXT
| SF_UNICODE
};
468 return flags
[format
];
471 static void set_font(LPCWSTR wszFaceName
)
473 HWND hReBarWnd
= GetDlgItem(hMainWnd
, IDC_REBAR
);
474 HWND hSizeListWnd
= GetDlgItem(hReBarWnd
, IDC_SIZELIST
);
475 HWND hFontListWnd
= GetDlgItem(hReBarWnd
, IDC_FONTLIST
);
476 HWND hFontListEditWnd
= (HWND
)SendMessageW(hFontListWnd
, CBEM_GETEDITCONTROL
, 0, 0);
479 ZeroMemory(&fmt
, sizeof(fmt
));
481 fmt
.cbSize
= sizeof(fmt
);
482 fmt
.dwMask
= CFM_FACE
;
484 lstrcpyW(fmt
.szFaceName
, wszFaceName
);
486 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
488 populate_size_list(hSizeListWnd
);
490 SendMessageW(hFontListEditWnd
, WM_SETTEXT
, 0, (LPARAM
)wszFaceName
);
493 static void set_default_font(void)
495 static const WCHAR richTextFont
[] = {'T','i','m','e','s',' ','N','e','w',' ',
496 'R','o','m','a','n',0};
497 static const WCHAR plainTextFont
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
501 ZeroMemory(&fmt
, sizeof(fmt
));
503 fmt
.cbSize
= sizeof(fmt
);
504 fmt
.dwMask
= CFM_FACE
| CFM_BOLD
| CFM_ITALIC
| CFM_UNDERLINE
;
507 if(fileFormat
& SF_RTF
)
510 font
= plainTextFont
;
512 lstrcpyW(fmt
.szFaceName
, font
);
514 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_DEFAULT
, (LPARAM
)&fmt
);
517 static void on_fontlist_modified(LPWSTR wszNewFaceName
)
520 ZeroMemory(&format
, sizeof(format
));
521 format
.cbSize
= sizeof(format
);
522 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);
524 if(lstrcmpW(format
.szFaceName
, wszNewFaceName
))
525 set_font(wszNewFaceName
);
528 static void dialog_choose_font(void)
533 HDC hDC
= GetDC(hMainWnd
);
535 ZeroMemory(&cf
, sizeof(cf
));
536 cf
.lStructSize
= sizeof(cf
);
537 cf
.hwndOwner
= hMainWnd
;
539 cf
.Flags
= CF_SCREENFONTS
| CF_NOSCRIPTSEL
| CF_INITTOLOGFONTSTRUCT
| CF_EFFECTS
| CF_NOVERTFONTS
;
541 ZeroMemory(&fmt
, sizeof(fmt
));
542 fmt
.cbSize
= sizeof(fmt
);
544 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
545 lstrcpyW(cf
.lpLogFont
->lfFaceName
, fmt
.szFaceName
);
546 cf
.lpLogFont
->lfItalic
= (fmt
.dwEffects
& CFE_ITALIC
) != 0;
547 cf
.lpLogFont
->lfWeight
= (fmt
.dwEffects
& CFE_BOLD
) ? FW_BOLD
: FW_NORMAL
;
548 cf
.lpLogFont
->lfUnderline
= (fmt
.dwEffects
& CFE_UNDERLINE
) != 0;
549 cf
.lpLogFont
->lfStrikeOut
= (fmt
.dwEffects
& CFE_STRIKEOUT
) != 0;
550 cf
.lpLogFont
->lfHeight
= -MulDiv(fmt
.yHeight
/ 20, GetDeviceCaps(hDC
, LOGPIXELSY
), 72);
551 cf
.rgbColors
= fmt
.crTextColor
;
555 ZeroMemory(&fmt
, sizeof(fmt
));
556 fmt
.cbSize
= sizeof(fmt
);
557 fmt
.dwMask
= CFM_BOLD
| CFM_ITALIC
| CFM_SIZE
| CFM_UNDERLINE
| CFM_STRIKEOUT
| CFM_COLOR
;
558 fmt
.yHeight
= cf
.iPointSize
* 2;
560 if(cf
.nFontType
& BOLD_FONTTYPE
)
561 fmt
.dwEffects
|= CFE_BOLD
;
562 if(cf
.nFontType
& ITALIC_FONTTYPE
)
563 fmt
.dwEffects
|= CFE_ITALIC
;
564 if(cf
.lpLogFont
->lfUnderline
)
565 fmt
.dwEffects
|= CFE_UNDERLINE
;
566 if(cf
.lpLogFont
->lfStrikeOut
)
567 fmt
.dwEffects
|= CFE_STRIKEOUT
;
569 fmt
.crTextColor
= cf
.rgbColors
;
571 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
572 set_font(cf
.lpLogFont
->lfFaceName
);
584 struct font_desc
*fonts
;
589 static BOOL
array_reserve(void **elements
, size_t *capacity
, size_t count
, size_t size
)
591 size_t new_capacity
, max_capacity
;
594 if (count
<= *capacity
)
597 max_capacity
= ~(SIZE_T
)0 / size
;
598 if (count
> max_capacity
)
601 new_capacity
= max(4, *capacity
);
602 while (new_capacity
< count
&& new_capacity
<= max_capacity
/ 2)
604 if (new_capacity
< count
)
605 new_capacity
= max_capacity
;
607 new_elements
= *elements
? realloc(*elements
, new_capacity
* size
) :
608 malloc(new_capacity
* size
);
612 *elements
= new_elements
;
613 *capacity
= new_capacity
;
618 static void add_font(struct font_array
*fonts
, LPCWSTR fontName
, DWORD fontType
, const NEWTEXTMETRICEXW
*ntmc
)
623 if (!array_reserve((void **)&fonts
->fonts
, &fonts
->capacity
, fonts
->count
+ 1, sizeof(*fonts
->fonts
)))
626 if (fontType
& RASTER_FONTTYPE
)
627 fontHeight
= ntmc
->ntmTm
.tmHeight
- ntmc
->ntmTm
.tmInternalLeading
;
630 fonts
->fonts
[idx
].name
= wcsdup(fontName
);
631 fonts
->fonts
[idx
].lParam
= MAKELONG(fontType
, fontHeight
);
636 static int CALLBACK
enum_font_proc(const LOGFONTW
*lpelfe
, const TEXTMETRICW
*lpntme
,
637 DWORD FontType
, LPARAM lParam
)
639 struct font_array
*fonts
= (void *)lParam
;
641 if (lpelfe
->lfFaceName
[0] == '@') return 1; /* ignore vertical fonts */
643 add_font(fonts
, lpelfe
->lfFaceName
, FontType
, (const NEWTEXTMETRICEXW
*)lpntme
);
648 static int __cdecl
fonts_desc_compare(const void *a
, const void *b
)
650 const struct font_desc
*left
= a
, *right
= b
;
651 return lstrcmpiW(left
->name
, right
->name
);
654 static void populate_font_list(HWND hListWnd
)
656 struct font_array font_array
= { 0 };
657 HDC hdc
= GetDC(hMainWnd
);
659 HWND hListEditWnd
= (HWND
)SendMessageW(hListWnd
, CBEM_GETEDITCONTROL
, 0, 0);
663 fontinfo
.lfCharSet
= DEFAULT_CHARSET
;
664 *fontinfo
.lfFaceName
= '\0';
665 fontinfo
.lfPitchAndFamily
= 0;
667 /* Collect font names, sort, remove duplicates. */
668 EnumFontFamiliesExW(hdc
, &fontinfo
, enum_font_proc
, (LPARAM
)&font_array
, 0);
670 qsort(font_array
.fonts
, font_array
.count
, sizeof(*font_array
.fonts
), fonts_desc_compare
);
672 for (i
= 1, j
= 0; i
< font_array
.count
; ++i
)
674 if (!lstrcmpiW(font_array
.fonts
[i
].name
, font_array
.fonts
[j
].name
))
676 free(font_array
.fonts
[i
].name
);
677 font_array
.fonts
[i
].name
= NULL
;
681 font_array
.fonts
[j
] = font_array
.fonts
[i
];
682 font_array
.fonts
[i
].name
= NULL
;
685 font_array
.count
= j
+ 1;
687 for (i
= 0; i
< font_array
.count
; ++i
)
689 COMBOBOXEXITEMW cbitem
= { 0 };
691 cbitem
.mask
= CBEIF_TEXT
| CBEIF_LPARAM
;
692 cbitem
.pszText
= font_array
.fonts
[i
].name
;
694 cbitem
.lParam
= font_array
.fonts
[i
].lParam
;
696 SendMessageW(hListWnd
, CBEM_INSERTITEMW
, 0, (LPARAM
)&cbitem
);
698 free(font_array
.fonts
[i
].name
);
700 free(font_array
.fonts
);
702 ZeroMemory(&fmt
, sizeof(fmt
));
703 fmt
.cbSize
= sizeof(fmt
);
704 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_DEFAULT
, (LPARAM
)&fmt
);
705 SendMessageW(hListEditWnd
, WM_SETTEXT
, 0, (LPARAM
)fmt
.szFaceName
);
708 static void update_window(void)
712 GetClientRect(hMainWnd
, &rect
);
714 OnSize(hMainWnd
, SIZE_RESTORED
, MAKELPARAM(rect
.right
, rect
.bottom
));
717 static BOOL
is_bar_visible(int bandId
)
719 return barState
[reg_formatindex(fileFormat
)] & (1 << bandId
);
722 static void store_bar_state(int bandId
, BOOL show
)
724 int formatIndex
= reg_formatindex(fileFormat
);
727 barState
[formatIndex
] |= (1 << bandId
);
729 barState
[formatIndex
] &= ~(1 << bandId
);
732 static void set_toolbar_state(int bandId
, BOOL show
)
734 HWND hwndReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
736 SendMessageW(hwndReBar
, RB_SHOWBAND
, SendMessageW(hwndReBar
, RB_IDTOINDEX
, bandId
, 0), show
);
738 if(bandId
== BANDID_TOOLBAR
)
740 REBARBANDINFOW rbbinfo
;
741 int index
= SendMessageW(hwndReBar
, RB_IDTOINDEX
, BANDID_FONTLIST
, 0);
743 rbbinfo
.cbSize
= REBARBANDINFOW_V6_SIZE
;
744 rbbinfo
.fMask
= RBBIM_STYLE
;
746 SendMessageW(hwndReBar
, RB_GETBANDINFOW
, index
, (LPARAM
)&rbbinfo
);
749 rbbinfo
.fStyle
&= ~RBBS_BREAK
;
751 rbbinfo
.fStyle
|= RBBS_BREAK
;
753 SendMessageW(hwndReBar
, RB_SETBANDINFOW
, index
, (LPARAM
)&rbbinfo
);
756 if(bandId
== BANDID_TOOLBAR
|| bandId
== BANDID_FORMATBAR
|| bandId
== BANDID_RULER
)
757 store_bar_state(bandId
, show
);
760 static void set_statusbar_state(BOOL show
)
762 HWND hStatusWnd
= GetDlgItem(hMainWnd
, IDC_STATUSBAR
);
764 ShowWindow(hStatusWnd
, show
? SW_SHOW
: SW_HIDE
);
765 store_bar_state(BANDID_STATUSBAR
, show
);
768 static void set_bar_states(void)
770 set_toolbar_state(BANDID_TOOLBAR
, is_bar_visible(BANDID_TOOLBAR
));
771 set_toolbar_state(BANDID_FONTLIST
, is_bar_visible(BANDID_FORMATBAR
));
772 set_toolbar_state(BANDID_SIZELIST
, is_bar_visible(BANDID_FORMATBAR
));
773 set_toolbar_state(BANDID_FORMATBAR
, is_bar_visible(BANDID_FORMATBAR
));
774 set_toolbar_state(BANDID_RULER
, is_bar_visible(BANDID_RULER
));
775 set_statusbar_state(is_bar_visible(BANDID_STATUSBAR
));
780 static void preview_exit(HWND hMainWnd
)
782 HMENU hMenu
= LoadMenuW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDM_MAINMENU
));
783 HWND hEditorWnd
= GetDlgItem(hMainWnd
, IDC_EDITOR
);
786 ShowWindow(hEditorWnd
, TRUE
);
788 close_preview(hMainWnd
);
790 SetMenu(hMainWnd
, hMenu
);
791 registry_read_filelist(hMainWnd
);
796 static void set_fileformat(WPARAM format
)
802 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
805 static void ShowOpenError(DWORD Code
)
811 case ERROR_ACCESS_DENIED
:
812 Message
= MAKEINTRESOURCEW(STRING_OPEN_ACCESS_DENIED
);
816 Message
= MAKEINTRESOURCEW(STRING_OPEN_FAILED
);
818 MessageBoxW(hMainWnd
, Message
, wszAppTitle
, MB_ICONEXCLAMATION
| MB_OK
);
821 static void DoOpenFile(LPCWSTR szOpenFileName
)
827 WPARAM format
= SF_TEXT
;
829 hFile
= CreateFileW(szOpenFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
830 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
831 if (hFile
== INVALID_HANDLE_VALUE
)
833 ShowOpenError(GetLastError());
837 ReadFile(hFile
, fileStart
, 5, &readOut
, NULL
);
838 SetFilePointer(hFile
, 0, NULL
, FILE_BEGIN
);
840 if(readOut
>= 2 && (BYTE
)fileStart
[0] == 0xff && (BYTE
)fileStart
[1] == 0xfe)
842 format
= SF_TEXT
| SF_UNICODE
;
843 SetFilePointer(hFile
, 2, NULL
, FILE_BEGIN
);
844 } else if(readOut
>= 5)
846 static const char header
[] = "{\\rtf";
847 static const BYTE STG_magic
[] = { 0xd0,0xcf,0x11,0xe0 };
849 if(!memcmp(header
, fileStart
, 5))
851 else if (!memcmp(STG_magic
, fileStart
, sizeof(STG_magic
)))
854 MessageBoxWithResStringW(hMainWnd
, MAKEINTRESOURCEW(STRING_OLE_STORAGE_NOT_SUPPORTED
),
855 wszAppTitle
, MB_OK
| MB_ICONEXCLAMATION
);
860 es
.dwCookie
= (DWORD_PTR
)hFile
;
861 es
.pfnCallback
= stream_in
;
864 set_fileformat(format
);
865 SendMessageW(hEditorWnd
, EM_STREAMIN
, format
, (LPARAM
)&es
);
869 SetFocus(hEditorWnd
);
871 set_caption(szOpenFileName
);
873 lstrcpyW(wszFileName
, szOpenFileName
);
874 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
875 registry_set_filelist(szOpenFileName
, hMainWnd
);
879 static void ShowWriteError(DWORD Code
)
885 case ERROR_ACCESS_DENIED
:
886 Message
= MAKEINTRESOURCEW(STRING_WRITE_ACCESS_DENIED
);
890 Message
= MAKEINTRESOURCEW(STRING_WRITE_FAILED
);
892 MessageBoxW(hMainWnd
, Message
, wszAppTitle
, MB_ICONEXCLAMATION
| MB_OK
);
895 static BOOL
DoSaveFile(LPCWSTR wszSaveFileName
, WPARAM format
)
901 hFile
= CreateFileW(wszSaveFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
902 FILE_ATTRIBUTE_NORMAL
, NULL
);
904 if(hFile
== INVALID_HANDLE_VALUE
)
906 ShowWriteError(GetLastError());
910 if(format
== (SF_TEXT
| SF_UNICODE
))
912 static const BYTE unicode
[] = {0xff,0xfe};
914 WriteFile(hFile
, &unicode
, sizeof(unicode
), &writeOut
, 0);
916 if(writeOut
!= sizeof(unicode
))
923 stream
.dwCookie
= (DWORD_PTR
)hFile
;
924 stream
.pfnCallback
= stream_out
;
926 ret
= SendMessageW(hEditorWnd
, EM_STREAMOUT
, format
, (LPARAM
)&stream
);
930 SetFocus(hEditorWnd
);
935 gt
.flags
= GTL_DEFAULT
;
938 if(SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
942 lstrcpyW(wszFileName
, wszSaveFileName
);
943 set_caption(wszFileName
);
944 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
945 set_fileformat(format
);
950 static BOOL
DialogSaveFile(void)
954 WCHAR wszFile
[MAX_PATH
] = {'\0'};
955 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
957 ZeroMemory(&sfn
, sizeof(sfn
));
959 sfn
.lStructSize
= sizeof(sfn
);
960 sfn
.Flags
= OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
| OFN_ENABLESIZING
;
961 sfn
.hwndOwner
= hMainWnd
;
962 sfn
.lpstrFilter
= wszFilter
;
963 sfn
.lpstrFile
= wszFile
;
964 sfn
.nMaxFile
= MAX_PATH
;
965 sfn
.lpstrDefExt
= wszDefExt
;
966 sfn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
968 while(GetSaveFileNameW(&sfn
))
970 if(fileformat_flags(sfn
.nFilterIndex
-1) != SF_RTF
)
972 if(MessageBoxWithResStringW(hMainWnd
, MAKEINTRESOURCEW(STRING_SAVE_LOSEFORMATTING
),
973 wszAppTitle
, MB_YESNO
| MB_ICONEXCLAMATION
) != IDYES
)
976 return DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
981 static BOOL
prompt_save_changes(void)
986 gt
.flags
= GTL_NUMCHARS
;
988 if(!SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
992 if(!SendMessageW(hEditorWnd
, EM_GETMODIFY
, 0, 0))
997 LPWSTR displayFileName
;
1002 displayFileName
= wszDefaultFileName
;
1004 displayFileName
= file_basename(wszFileName
);
1006 text
= calloc(lstrlenW(displayFileName
)+lstrlenW(wszSaveChanges
), sizeof(WCHAR
));
1011 wsprintfW(text
, wszSaveChanges
, displayFileName
);
1013 ret
= MessageBoxW(hMainWnd
, text
, wszAppTitle
, MB_YESNOCANCEL
| MB_ICONEXCLAMATION
);
1024 return DoSaveFile(wszFileName
, fileFormat
);
1025 return DialogSaveFile();
1033 static void DialogOpenFile(void)
1037 WCHAR wszFile
[MAX_PATH
] = {'\0'};
1038 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
1040 ZeroMemory(&ofn
, sizeof(ofn
));
1042 ofn
.lStructSize
= sizeof(ofn
);
1043 ofn
.Flags
= OFN_HIDEREADONLY
| OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
| OFN_ENABLESIZING
;
1044 ofn
.hwndOwner
= hMainWnd
;
1045 ofn
.lpstrFilter
= wszFilter
;
1046 ofn
.lpstrFile
= wszFile
;
1047 ofn
.nMaxFile
= MAX_PATH
;
1048 ofn
.lpstrDefExt
= wszDefExt
;
1049 ofn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
1051 if(GetOpenFileNameW(&ofn
))
1053 if(prompt_save_changes())
1054 DoOpenFile(ofn
.lpstrFile
);
1058 static void dialog_about(void)
1060 HICON icon
= LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_WORDPAD
), IMAGE_ICON
, 48, 48, LR_SHARED
);
1061 ShellAboutW(hMainWnd
, wszAppTitle
, 0, icon
);
1064 static INT_PTR CALLBACK
formatopts_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1070 LPPROPSHEETPAGEW ps
= (LPPROPSHEETPAGEW
)lParam
;
1073 HWND hIdWnd
= GetDlgItem(hWnd
, IDC_PAGEFMT_ID
);
1075 sprintf(id
, "%d\n", (int)ps
->lParam
);
1076 SetWindowTextA(hIdWnd
, id
);
1077 if(wordWrap
[ps
->lParam
] == ID_WORDWRAP_NONE
)
1078 wrap
= IDC_PAGEFMT_WN
;
1079 else if(wordWrap
[ps
->lParam
] == ID_WORDWRAP_WINDOW
)
1080 wrap
= IDC_PAGEFMT_WW
;
1081 else if(wordWrap
[ps
->lParam
] == ID_WORDWRAP_MARGIN
)
1082 wrap
= IDC_PAGEFMT_WM
;
1085 CheckRadioButton(hWnd
, IDC_PAGEFMT_WN
,
1086 IDC_PAGEFMT_WM
, wrap
);
1088 if(barState
[ps
->lParam
] & (1 << BANDID_TOOLBAR
))
1089 CheckDlgButton(hWnd
, IDC_PAGEFMT_TB
, TRUE
);
1090 if(barState
[ps
->lParam
] & (1 << BANDID_FORMATBAR
))
1091 CheckDlgButton(hWnd
, IDC_PAGEFMT_FB
, TRUE
);
1092 if(barState
[ps
->lParam
] & (1 << BANDID_RULER
))
1093 CheckDlgButton(hWnd
, IDC_PAGEFMT_RU
, TRUE
);
1094 if(barState
[ps
->lParam
] & (1 << BANDID_STATUSBAR
))
1095 CheckDlgButton(hWnd
, IDC_PAGEFMT_SB
, TRUE
);
1100 switch(LOWORD(wParam
))
1102 case IDC_PAGEFMT_WN
:
1103 case IDC_PAGEFMT_WW
:
1104 case IDC_PAGEFMT_WM
:
1105 CheckRadioButton(hWnd
, IDC_PAGEFMT_WN
, IDC_PAGEFMT_WM
,
1109 case IDC_PAGEFMT_TB
:
1110 case IDC_PAGEFMT_FB
:
1111 case IDC_PAGEFMT_RU
:
1112 case IDC_PAGEFMT_SB
:
1113 CheckDlgButton(hWnd
, LOWORD(wParam
),
1114 !IsDlgButtonChecked(hWnd
, LOWORD(wParam
)));
1120 LPNMHDR header
= (LPNMHDR
)lParam
;
1121 if(header
->code
== PSN_APPLY
)
1123 HWND hIdWnd
= GetDlgItem(hWnd
, IDC_PAGEFMT_ID
);
1127 GetWindowTextA(hIdWnd
, sid
, 4);
1129 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_WN
))
1130 wordWrap
[id
] = ID_WORDWRAP_NONE
;
1131 else if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_WW
))
1132 wordWrap
[id
] = ID_WORDWRAP_WINDOW
;
1133 else if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_WM
))
1134 wordWrap
[id
] = ID_WORDWRAP_MARGIN
;
1136 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_TB
))
1137 barState
[id
] |= (1 << BANDID_TOOLBAR
);
1139 barState
[id
] &= ~(1 << BANDID_TOOLBAR
);
1141 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_FB
))
1142 barState
[id
] |= (1 << BANDID_FORMATBAR
);
1144 barState
[id
] &= ~(1 << BANDID_FORMATBAR
);
1146 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_RU
))
1147 barState
[id
] |= (1 << BANDID_RULER
);
1149 barState
[id
] &= ~(1 << BANDID_RULER
);
1151 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_SB
))
1152 barState
[id
] |= (1 << BANDID_STATUSBAR
);
1154 barState
[id
] &= ~(1 << BANDID_STATUSBAR
);
1162 static void dialog_viewproperties(void)
1164 PROPSHEETPAGEW psp
[2];
1165 PROPSHEETHEADERW psh
;
1167 HINSTANCE hInstance
= GetModuleHandleW(0);
1168 LPCPROPSHEETPAGEW ppsp
= (LPCPROPSHEETPAGEW
)&psp
;
1170 psp
[0].dwSize
= sizeof(PROPSHEETPAGEW
);
1171 psp
[0].dwFlags
= PSP_USETITLE
;
1172 psp
[0].pszTemplate
= MAKEINTRESOURCEW(IDD_FORMATOPTS
);
1173 psp
[0].pfnDlgProc
= formatopts_proc
;
1174 psp
[0].hInstance
= hInstance
;
1175 psp
[0].lParam
= reg_formatindex(SF_TEXT
);
1176 psp
[0].pfnCallback
= NULL
;
1177 psp
[0].pszTitle
= MAKEINTRESOURCEW(STRING_VIEWPROPS_TEXT
);
1178 for(i
= 1; i
< ARRAY_SIZE(psp
); i
++)
1180 psp
[i
].dwSize
= psp
[0].dwSize
;
1181 psp
[i
].dwFlags
= psp
[0].dwFlags
;
1182 psp
[i
].pszTemplate
= psp
[0].pszTemplate
;
1183 psp
[i
].pfnDlgProc
= psp
[0].pfnDlgProc
;
1184 psp
[i
].hInstance
= psp
[0].hInstance
;
1185 psp
[i
].lParam
= reg_formatindex(SF_RTF
);
1186 psp
[i
].pfnCallback
= psp
[0].pfnCallback
;
1187 psp
[i
].pszTitle
= MAKEINTRESOURCEW(STRING_VIEWPROPS_RICHTEXT
);
1190 psh
.dwSize
= sizeof(psh
);
1191 psh
.dwFlags
= PSH_USEICONID
| PSH_PROPSHEETPAGE
| PSH_NOAPPLYNOW
;
1192 psh
.hwndParent
= hMainWnd
;
1193 psh
.hInstance
= hInstance
;
1194 psh
.pszCaption
= MAKEINTRESOURCEW(STRING_VIEWPROPS_TITLE
);
1195 psh
.nPages
= ARRAY_SIZE(psp
);
1197 psh
.pszIcon
= MAKEINTRESOURCEW(IDI_WORDPAD
);
1199 if(fileFormat
& SF_RTF
)
1203 PropertySheetW(&psh
);
1205 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
1208 static void HandleCommandLine(LPWSTR cmdline
)
1211 BOOL opt_print
= FALSE
;
1213 /* skip white space */
1214 while (*cmdline
== ' ') cmdline
++;
1216 /* skip executable name */
1217 delimiter
= (*cmdline
== '"' ? '"' : ' ');
1219 if (*cmdline
== delimiter
) cmdline
++;
1220 while (*cmdline
&& *cmdline
!= delimiter
) cmdline
++;
1221 if (*cmdline
== delimiter
) cmdline
++;
1225 while (*cmdline
== ' ' || *cmdline
== '\t') cmdline
++;
1227 if (*cmdline
== '-' || *cmdline
== '/')
1229 if (!cmdline
[2] || isspace(cmdline
[2]))
1240 /* a filename starting by / */
1247 /* file name is passed on the command line */
1248 if (cmdline
[0] == '"')
1251 cmdline
[lstrlenW(cmdline
) - 1] = 0;
1253 DoOpenFile(cmdline
);
1254 InvalidateRect(hMainWnd
, NULL
, FALSE
);
1258 MessageBoxWithResStringW(hMainWnd
, MAKEINTRESOURCEW(STRING_PRINTING_NOT_IMPLEMENTED
), wszAppTitle
, MB_OK
);
1261 static LRESULT
handle_findmsg(LPFINDREPLACEW pFr
)
1263 if(pFr
->Flags
& FR_DIALOGTERM
)
1266 pFr
->Flags
= FR_FINDNEXT
;
1270 if(pFr
->Flags
& FR_FINDNEXT
|| pFr
->Flags
& FR_REPLACE
|| pFr
->Flags
& FR_REPLACEALL
)
1272 FINDREPLACE_custom
*custom_data
= (FINDREPLACE_custom
*)pFr
->lCustData
;
1277 HMENU hMenu
= GetMenu(hMainWnd
);
1280 mi
.cbSize
= sizeof(mi
);
1281 mi
.fMask
= MIIM_DATA
;
1283 SetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
1285 /* Make sure find field is saved. */
1286 if (pFr
->lpstrFindWhat
!= custom_data
->findBuffer
)
1288 lstrcpynW(custom_data
->findBuffer
, pFr
->lpstrFindWhat
,
1289 ARRAY_SIZE(custom_data
->findBuffer
));
1290 pFr
->lpstrFindWhat
= custom_data
->findBuffer
;
1293 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&sel
.cpMin
, (LPARAM
)&sel
.cpMax
);
1294 if(custom_data
->endPos
== -1) {
1295 custom_data
->endPos
= sel
.cpMin
;
1296 custom_data
->wrapped
= FALSE
;
1299 flags
= FR_DOWN
| (pFr
->Flags
& (FR_MATCHCASE
| FR_WHOLEWORD
));
1300 ft
.lpstrText
= pFr
->lpstrFindWhat
;
1302 /* Only replace the existing selection if it is an exact match. */
1303 if (sel
.cpMin
!= sel
.cpMax
&&
1304 (pFr
->Flags
& FR_REPLACE
|| pFr
->Flags
& FR_REPLACEALL
))
1307 SendMessageW(hEditorWnd
, EM_FINDTEXTEXW
, flags
, (LPARAM
)&ft
);
1308 if (ft
.chrgText
.cpMin
== sel
.cpMin
&& ft
.chrgText
.cpMax
== sel
.cpMax
) {
1309 SendMessageW(hEditorWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)pFr
->lpstrReplaceWith
);
1310 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&sel
.cpMin
, (LPARAM
)&sel
.cpMax
);
1314 /* Search from the start of the selection, but exclude the first character
1315 * from search if there is a selection. */
1316 ft
.chrg
.cpMin
= sel
.cpMin
;
1317 if (sel
.cpMin
!= sel
.cpMax
)
1320 /* Search to the end, then wrap around and search from the start. */
1321 if (!custom_data
->wrapped
) {
1323 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTEXW
, flags
, (LPARAM
)&ft
);
1325 custom_data
->wrapped
= TRUE
;
1331 ft
.chrg
.cpMax
= custom_data
->endPos
+ lstrlenW(pFr
->lpstrFindWhat
) - 1;
1332 if (ft
.chrg
.cpMax
> ft
.chrg
.cpMin
)
1333 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTEXW
, flags
, (LPARAM
)&ft
);
1337 custom_data
->endPos
= -1;
1338 EnableWindow(hMainWnd
, FALSE
);
1339 MessageBoxWithResStringW(hFindWnd
, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED
),
1340 wszAppTitle
, MB_OK
| MB_ICONASTERISK
| MB_TASKMODAL
);
1341 EnableWindow(hMainWnd
, TRUE
);
1343 SendMessageW(hEditorWnd
, EM_SETSEL
, ft
.chrgText
.cpMin
, ft
.chrgText
.cpMax
);
1344 SendMessageW(hEditorWnd
, EM_SCROLLCARET
, 0, 0);
1346 if (pFr
->Flags
& FR_REPLACEALL
)
1347 return handle_findmsg(pFr
);
1354 static void dialog_find(LPFINDREPLACEW fr
, BOOL replace
)
1356 static WCHAR selBuffer
[128];
1357 static WCHAR replaceBuffer
[128];
1358 static FINDREPLACE_custom custom_data
;
1359 static const WCHAR endl
= '\r';
1362 /* Allow only one search/replace dialog to open */
1363 if(hFindWnd
!= NULL
)
1365 SetActiveWindow(hFindWnd
);
1369 ZeroMemory(fr
, sizeof(FINDREPLACEW
));
1370 fr
->lStructSize
= sizeof(FINDREPLACEW
);
1371 fr
->hwndOwner
= hMainWnd
;
1372 fr
->Flags
= FR_HIDEUPDOWN
;
1373 /* Find field is filled with the selected text if it is non-empty
1374 * and stays within the same paragraph, otherwise the previous
1375 * find field is used. */
1376 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&ft
.chrg
.cpMin
,
1377 (LPARAM
)&ft
.chrg
.cpMax
);
1378 ft
.lpstrText
= &endl
;
1379 if (ft
.chrg
.cpMin
!= ft
.chrg
.cpMax
&&
1380 SendMessageW(hEditorWnd
, EM_FINDTEXTW
, FR_DOWN
, (LPARAM
)&ft
) == -1)
1382 /* Use a temporary buffer for the selected text so that the saved
1383 * find field is only overwritten when a find/replace is clicked. */
1384 GETTEXTEX gt
= {sizeof(selBuffer
), GT_SELECTION
, 1200, NULL
, NULL
};
1385 SendMessageW(hEditorWnd
, EM_GETTEXTEX
, (WPARAM
)>
, (LPARAM
)selBuffer
);
1386 fr
->lpstrFindWhat
= selBuffer
;
1388 fr
->lpstrFindWhat
= custom_data
.findBuffer
;
1390 fr
->lpstrReplaceWith
= replaceBuffer
;
1391 custom_data
.endPos
= -1;
1392 custom_data
.wrapped
= FALSE
;
1393 fr
->lCustData
= (LPARAM
)&custom_data
;
1394 fr
->wFindWhatLen
= sizeof(custom_data
.findBuffer
);
1395 fr
->wReplaceWithLen
= sizeof(replaceBuffer
);
1398 hFindWnd
= ReplaceTextW(fr
);
1400 hFindWnd
= FindTextW(fr
);
1403 static int units_to_twips(UNIT unit
, float number
)
1410 twips
= (int)(number
* 1000.0 / (float)CENTMM_PER_INCH
* (float)TWIPS_PER_INCH
);
1414 twips
= (int)(number
* (float)TWIPS_PER_INCH
);
1418 twips
= (int)(number
* (0.0138 * (float)TWIPS_PER_INCH
));
1425 static void append_current_units(LPWSTR buffer
)
1427 static const WCHAR space
[] = {' ', 0};
1428 lstrcatW(buffer
, space
);
1429 lstrcatW(buffer
, units_cmW
);
1432 static void number_with_units(LPWSTR buffer
, int number
)
1434 static const WCHAR fmt
[] = {'%','.','2','f',' ','%','s','\0'};
1435 float converted
= (float)number
/ (float)TWIPS_PER_INCH
*(float)CENTMM_PER_INCH
/ 1000.0;
1437 swprintf(buffer
, MAX_STRING_LEN
, fmt
, converted
, units_cmW
);
1440 static BOOL
get_comboexlist_selection(HWND hComboEx
, LPWSTR wszBuffer
, UINT bufferLength
)
1442 COMBOBOXEXITEMW cbItem
;
1443 COMBOBOXINFO cbInfo
;
1447 hCombo
= (HWND
)SendMessageW(hComboEx
, CBEM_GETCOMBOCONTROL
, 0, 0);
1450 cbInfo
.cbSize
= sizeof(COMBOBOXINFO
);
1451 result
= SendMessageW(hCombo
, CB_GETCOMBOBOXINFO
, 0, (LPARAM
)&cbInfo
);
1454 hList
= cbInfo
.hwndList
;
1455 idx
= SendMessageW(hList
, LB_GETCURSEL
, 0, 0);
1459 ZeroMemory(&cbItem
, sizeof(cbItem
));
1460 cbItem
.mask
= CBEIF_TEXT
;
1462 cbItem
.pszText
= wszBuffer
;
1463 cbItem
.cchTextMax
= bufferLength
-1;
1464 result
= SendMessageW(hComboEx
, CBEM_GETITEMW
, 0, (LPARAM
)&cbItem
);
1469 static INT_PTR CALLBACK
datetime_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1475 WCHAR buffer
[MAX_STRING_LEN
];
1477 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
1480 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, 0, (LPWSTR
)&buffer
,
1482 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1483 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, 0, (LPWSTR
)&buffer
,
1485 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1486 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, 0, (LPWSTR
)&buffer
, MAX_STRING_LEN
);
1487 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1489 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1494 switch(LOWORD(wParam
))
1497 if (HIWORD(wParam
) != LBN_DBLCLK
)
1504 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
1506 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1510 WCHAR buffer
[MAX_STRING_LEN
];
1511 SendMessageW(hListWnd
, LB_GETTEXT
, index
, (LPARAM
)&buffer
);
1512 SendMessageW(hEditorWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)&buffer
);
1518 EndDialog(hWnd
, wParam
);
1525 static INT_PTR CALLBACK
newfile_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1531 HINSTANCE hInstance
= GetModuleHandleW(0);
1532 WCHAR buffer
[MAX_STRING_LEN
];
1533 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1535 LoadStringW(hInstance
, STRING_NEWFILE_RICHTEXT
, buffer
, MAX_STRING_LEN
);
1536 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1537 LoadStringW(hInstance
, STRING_NEWFILE_TXT
, buffer
, MAX_STRING_LEN
);
1538 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1539 LoadStringW(hInstance
, STRING_NEWFILE_TXT_UNICODE
, buffer
, MAX_STRING_LEN
);
1540 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1542 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1547 switch(LOWORD(wParam
))
1552 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1553 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1556 EndDialog(hWnd
, MAKELONG(fileformat_flags(index
),0));
1561 EndDialog(hWnd
, MAKELONG(ID_NEWFILE_ABORT
,0));
1568 static INT_PTR CALLBACK
paraformat_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1570 static const WORD ALIGNMENT_VALUES
[] = {PFA_LEFT
, PFA_RIGHT
, PFA_CENTER
};
1576 HINSTANCE hInstance
= GetModuleHandleW(0);
1577 WCHAR buffer
[MAX_STRING_LEN
];
1578 HWND hListWnd
= GetDlgItem(hWnd
, IDC_PARA_ALIGN
);
1579 HWND hLeftWnd
= GetDlgItem(hWnd
, IDC_PARA_LEFT
);
1580 HWND hRightWnd
= GetDlgItem(hWnd
, IDC_PARA_RIGHT
);
1581 HWND hFirstWnd
= GetDlgItem(hWnd
, IDC_PARA_FIRST
);
1585 LoadStringW(hInstance
, STRING_ALIGN_LEFT
, buffer
,
1587 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1588 LoadStringW(hInstance
, STRING_ALIGN_RIGHT
, buffer
,
1590 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1591 LoadStringW(hInstance
, STRING_ALIGN_CENTER
, buffer
,
1593 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1595 pf
.cbSize
= sizeof(pf
);
1596 pf
.dwMask
= PFM_ALIGNMENT
| PFM_OFFSET
| PFM_RIGHTINDENT
|
1598 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1600 if(pf
.wAlignment
== PFA_RIGHT
)
1602 else if(pf
.wAlignment
== PFA_CENTER
)
1605 SendMessageW(hListWnd
, CB_SETCURSEL
, index
, 0);
1607 number_with_units(buffer
, pf
.dxStartIndent
+ pf
.dxOffset
);
1608 SetWindowTextW(hLeftWnd
, buffer
);
1609 number_with_units(buffer
, pf
.dxRightIndent
);
1610 SetWindowTextW(hRightWnd
, buffer
);
1611 number_with_units(buffer
, -pf
.dxOffset
);
1612 SetWindowTextW(hFirstWnd
, buffer
);
1617 switch(LOWORD(wParam
))
1621 HWND hListWnd
= GetDlgItem(hWnd
, IDC_PARA_ALIGN
);
1622 HWND hLeftWnd
= GetDlgItem(hWnd
, IDC_PARA_LEFT
);
1623 HWND hRightWnd
= GetDlgItem(hWnd
, IDC_PARA_RIGHT
);
1624 HWND hFirstWnd
= GetDlgItem(hWnd
, IDC_PARA_FIRST
);
1625 WCHAR buffer
[MAX_STRING_LEN
];
1631 BOOL in_list
= FALSE
;
1633 pf
.cbSize
= sizeof(pf
);
1634 pf
.dwMask
= PFM_NUMBERING
;
1635 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1636 if ((pf
.dwMask
& PFM_NUMBERING
) && pf
.wNumbering
)
1639 index
= SendMessageW(hListWnd
, CB_GETCURSEL
, 0, 0);
1640 pf
.wAlignment
= ALIGNMENT_VALUES
[index
];
1642 GetWindowTextW(hLeftWnd
, buffer
, MAX_STRING_LEN
);
1643 if(number_from_string(buffer
, &num
, &unit
))
1645 pf
.dxOffset
= units_to_twips(unit
, num
);
1646 GetWindowTextW(hRightWnd
, buffer
, MAX_STRING_LEN
);
1647 if(number_from_string(buffer
, &num
, &unit
))
1649 pf
.dxRightIndent
= units_to_twips(unit
, num
);
1650 GetWindowTextW(hFirstWnd
, buffer
, MAX_STRING_LEN
);
1651 if(number_from_string(buffer
, &num
, &unit
))
1653 pf
.dxStartIndent
= units_to_twips(unit
, num
);
1657 MessageBoxWithResStringW(hMainWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
1658 wszAppTitle
, MB_OK
| MB_ICONASTERISK
);
1662 if (pf
.dxOffset
+ pf
.dxStartIndent
< 0
1663 && pf
.dxStartIndent
< 0)
1665 /* The first line is before the left edge, so
1666 * make sure it is at the left edge. */
1667 pf
.dxOffset
= -pf
.dxStartIndent
;
1668 } else if (pf
.dxOffset
< 0) {
1669 /* The second and following lines are before
1670 * the left edge, so set it to be at the left
1671 * edge, and adjust the first line since it
1672 * is relative to it. */
1673 pf
.dxStartIndent
= max(pf
.dxStartIndent
+ pf
.dxOffset
, 0);
1676 /* Internally the dxStartIndent is the absolute
1677 * offset for the first line and dxOffset is
1678 * to it value as opposed how it is displayed with
1679 * the first line being the relative value.
1680 * These two lines make the adjustments. */
1681 pf
.dxStartIndent
= pf
.dxStartIndent
+ pf
.dxOffset
;
1682 pf
.dxOffset
= pf
.dxOffset
- pf
.dxStartIndent
;
1684 pf
.cbSize
= sizeof(pf
);
1685 pf
.dwMask
= PFM_ALIGNMENT
| PFM_OFFSET
| PFM_RIGHTINDENT
|
1689 pf
.wNumberingTab
= max(pf
.dxOffset
, 0);
1690 pf
.dwMask
|= PFM_NUMBERINGTAB
;
1693 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1699 EndDialog(hWnd
, wParam
);
1706 static INT_PTR CALLBACK
tabstops_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1712 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1714 WCHAR buffer
[MAX_STRING_LEN
];
1717 pf
.cbSize
= sizeof(pf
);
1718 pf
.dwMask
= PFM_TABSTOPS
;
1719 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1720 SendMessageW(hTabWnd
, CB_LIMITTEXT
, MAX_STRING_LEN
-1, 0);
1722 for(i
= 0; i
< pf
.cTabCount
; i
++)
1724 number_with_units(buffer
, pf
.rgxTabs
[i
]);
1725 SendMessageW(hTabWnd
, CB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1732 switch(LOWORD(wParam
))
1736 HWND hTabWnd
= (HWND
)lParam
;
1737 HWND hAddWnd
= GetDlgItem(hWnd
, ID_TAB_ADD
);
1738 HWND hDelWnd
= GetDlgItem(hWnd
, ID_TAB_DEL
);
1739 HWND hEmptyWnd
= GetDlgItem(hWnd
, ID_TAB_EMPTY
);
1741 if(GetWindowTextLengthW(hTabWnd
))
1742 EnableWindow(hAddWnd
, TRUE
);
1744 EnableWindow(hAddWnd
, FALSE
);
1746 if(SendMessageW(hTabWnd
, CB_GETCOUNT
, 0, 0))
1748 EnableWindow(hEmptyWnd
, TRUE
);
1750 if(SendMessageW(hTabWnd
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
1751 EnableWindow(hDelWnd
, FALSE
);
1753 EnableWindow(hDelWnd
, TRUE
);
1756 EnableWindow(hEmptyWnd
, FALSE
);
1763 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1764 WCHAR buffer
[MAX_STRING_LEN
];
1767 GetWindowTextW(hTabWnd
, buffer
, MAX_STRING_LEN
);
1768 append_current_units(buffer
);
1770 if(SendMessageW(hTabWnd
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)&buffer
) == CB_ERR
)
1773 int item_count
= SendMessageW(hTabWnd
, CB_GETCOUNT
, 0, 0);
1775 if(!number_from_string(buffer
, &number
, &unit
))
1777 MessageBoxWithResStringW(hWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
1778 wszAppTitle
, MB_OK
| MB_ICONINFORMATION
);
1779 } else if (item_count
>= MAX_TAB_STOPS
) {
1780 MessageBoxWithResStringW(hWnd
, MAKEINTRESOURCEW(STRING_MAX_TAB_STOPS
),
1781 wszAppTitle
, MB_OK
| MB_ICONINFORMATION
);
1784 float next_number
= -1;
1785 int next_number_in_twips
= -1;
1786 int insert_number
= units_to_twips(unit
, number
);
1788 /* linear search for position to insert the string */
1789 for(i
= 0; i
< item_count
; i
++)
1791 SendMessageW(hTabWnd
, CB_GETLBTEXT
, i
, (LPARAM
)&buffer
);
1792 number_from_string(buffer
, &next_number
, &unit
);
1793 next_number_in_twips
= units_to_twips(unit
, next_number
);
1794 if (insert_number
<= next_number_in_twips
)
1797 if (insert_number
!= next_number_in_twips
)
1799 number_with_units(buffer
, insert_number
);
1800 SendMessageW(hTabWnd
, CB_INSERTSTRING
, i
, (LPARAM
)&buffer
);
1801 SetWindowTextW(hTabWnd
, 0);
1811 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1813 ret
= SendMessageW(hTabWnd
, CB_GETCURSEL
, 0, 0);
1815 SendMessageW(hTabWnd
, CB_DELETESTRING
, ret
, 0);
1821 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1822 SendMessageW(hTabWnd
, CB_RESETCONTENT
, 0, 0);
1829 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1831 WCHAR buffer
[MAX_STRING_LEN
];
1836 pf
.cbSize
= sizeof(pf
);
1837 pf
.dwMask
= PFM_TABSTOPS
;
1839 for(i
= 0; SendMessageW(hTabWnd
, CB_GETLBTEXT
, i
,
1840 (LPARAM
)&buffer
) != CB_ERR
&&
1841 i
< MAX_TAB_STOPS
; i
++)
1843 number_from_string(buffer
, &number
, &unit
);
1844 pf
.rgxTabs
[i
] = units_to_twips(unit
, number
);
1847 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1851 EndDialog(hWnd
, wParam
);
1858 static LRESULT
OnCreate( HWND hWnd
)
1860 HWND hToolBarWnd
, hFormatBarWnd
, hReBarWnd
, hFontListWnd
, hSizeListWnd
, hRulerWnd
;
1861 HINSTANCE hInstance
= GetModuleHandleW(0);
1864 int nStdBitmaps
= 0;
1870 SIZE name_sz
, size_sz
;
1872 static const WCHAR wszRichEditDll
[] = {'R','I','C','H','E','D','2','0','.','D','L','L','\0'};
1873 static const WCHAR wszRichEditText
[] = {'R','i','c','h','E','d','i','t',' ','t','e','x','t','\0'};
1874 static const WCHAR font_text
[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0}; /* a long font name */
1875 static const WCHAR size_text
[] = {' ','0','0',0}; /* enough for two digits */
1877 CreateStatusWindowW(CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
, wszRichEditText
, hWnd
, IDC_STATUSBAR
);
1879 hReBarWnd
= CreateWindowExW(WS_EX_TOOLWINDOW
, REBARCLASSNAMEW
, NULL
,
1880 CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|RBS_VARHEIGHT
|CCS_TOP
,
1881 CW_USEDEFAULT
, CW_USEDEFAULT
, 0, 0, hWnd
, (HMENU
)IDC_REBAR
, hInstance
, NULL
);
1883 rbi
.cbSize
= sizeof(rbi
);
1886 if(!SendMessageW(hReBarWnd
, RB_SETBARINFO
, 0, (LPARAM
)&rbi
))
1889 hToolBarWnd
= CreateToolbarEx(hReBarWnd
, CCS_NOPARENTALIGN
|CCS_NOMOVEY
|WS_VISIBLE
|WS_CHILD
|TBSTYLE_TOOLTIPS
,
1891 1, hInstance
, IDB_TOOLBAR
,
1893 24, 24, 16, 16, sizeof(TBBUTTON
));
1896 dpi
= GetDeviceCaps(hdc
, LOGPIXELSY
);
1897 ReleaseDC(hWnd
, hdc
);
1899 ab
.hInst
= HINST_COMMCTRL
;
1900 ab
.nID
= dpi
>= 120 ? IDB_STD_LARGE_COLOR
: IDB_STD_SMALL_COLOR
;
1901 nStdBitmaps
= SendMessageW(hToolBarWnd
, TB_ADDBITMAP
, 0, (LPARAM
)&ab
);
1903 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILENEW
, ID_FILE_NEW
);
1904 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILEOPEN
, ID_FILE_OPEN
);
1905 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILESAVE
, ID_FILE_SAVE
);
1906 AddSeparator(hToolBarWnd
);
1907 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINT
, ID_PRINT_QUICK
);
1908 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINTPRE
, ID_PREVIEW
);
1909 AddSeparator(hToolBarWnd
);
1910 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FIND
, ID_FIND
);
1911 AddSeparator(hToolBarWnd
);
1912 AddButton(hToolBarWnd
, nStdBitmaps
+STD_CUT
, ID_EDIT_CUT
);
1913 AddButton(hToolBarWnd
, nStdBitmaps
+STD_COPY
, ID_EDIT_COPY
);
1914 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PASTE
, ID_EDIT_PASTE
);
1915 AddButton(hToolBarWnd
, nStdBitmaps
+STD_UNDO
, ID_EDIT_UNDO
);
1916 AddButton(hToolBarWnd
, nStdBitmaps
+STD_REDOW
, ID_EDIT_REDO
);
1917 AddSeparator(hToolBarWnd
);
1918 AddButton(hToolBarWnd
, 0, ID_DATETIME
);
1920 SendMessageW(hToolBarWnd
, TB_AUTOSIZE
, 0, 0);
1921 height
= HIWORD(SendMessageW(hToolBarWnd
, TB_GETBUTTONSIZE
, 0, 0));
1923 hFontListWnd
= CreateWindowExW(0, WC_COMBOBOXEXW
, NULL
,
1924 WS_BORDER
| WS_VISIBLE
| WS_CHILD
| CBS_DROPDOWN
| CBS_SORT
,
1925 0, 0, 200, 150, hReBarWnd
, (HMENU
)IDC_FONTLIST
, hInstance
, NULL
);
1926 GetWindowRect(hFontListWnd
, &rect
);
1927 height
= max(height
, rect
.bottom
- rect
.top
);
1929 SendMessageW(hToolBarWnd
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(height
, height
));
1931 rbb
.cbSize
= REBARBANDINFOW_V6_SIZE
;
1932 rbb
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
| RBBIM_STYLE
| RBBIM_ID
;
1933 rbb
.fStyle
= RBBS_CHILDEDGE
| RBBS_BREAK
| RBBS_NOGRIPPER
;
1935 rbb
.hwndChild
= hToolBarWnd
;
1937 rbb
.cyChild
= rbb
.cyMinChild
= height
;
1938 rbb
.wID
= BANDID_TOOLBAR
;
1940 SendMessageW(hReBarWnd
, RB_INSERTBANDW
, -1, (LPARAM
)&rbb
);
1942 font
= (HFONT
)SendMessageW(hFontListWnd
, WM_GETFONT
, 0, 0);
1943 hdc
= GetDC(hFontListWnd
);
1944 font
= SelectObject(hdc
, font
);
1945 GetTextExtentPointW(hdc
, font_text
, ARRAY_SIZE(font_text
) - 1, &name_sz
);
1946 GetTextExtentPointW(hdc
, size_text
, ARRAY_SIZE(size_text
) - 1, &size_sz
);
1947 font
= SelectObject(hdc
, font
);
1948 ReleaseDC(hFontListWnd
, hdc
);
1949 rbb
.hwndChild
= hFontListWnd
;
1950 rbb
.cx
= MulDiv(name_sz
.cx
, 3, 2) + height
; /* height is space for the dropdown arrow */
1951 rbb
.wID
= BANDID_FONTLIST
;
1953 SendMessageW(hReBarWnd
, RB_INSERTBANDW
, -1, (LPARAM
)&rbb
);
1955 hSizeListWnd
= CreateWindowExW(0, WC_COMBOBOXEXW
, NULL
,
1956 WS_BORDER
| WS_VISIBLE
| WS_CHILD
| CBS_DROPDOWN
,
1957 0, 0, 50, 150, hReBarWnd
, (HMENU
)IDC_SIZELIST
, hInstance
, NULL
);
1959 rbb
.hwndChild
= hSizeListWnd
;
1960 rbb
.cx
= MulDiv(size_sz
.cx
, 3, 2) + height
; /* height is space for the dropdown arrow */
1961 rbb
.fStyle
^= RBBS_BREAK
;
1962 rbb
.wID
= BANDID_SIZELIST
;
1964 SendMessageW(hReBarWnd
, RB_INSERTBANDW
, -1, (LPARAM
)&rbb
);
1966 hFormatBarWnd
= CreateToolbarEx(hReBarWnd
,
1967 CCS_NOPARENTALIGN
| CCS_NOMOVEY
| WS_VISIBLE
| TBSTYLE_TOOLTIPS
,
1968 IDC_FORMATBAR
, 8, hInstance
, IDB_FORMATBAR
, NULL
, 0, 16, 16, 16, 16, sizeof(TBBUTTON
));
1970 SendMessageW(hFormatBarWnd
, TB_SETEXTENDEDSTYLE
, 0, TBSTYLE_EX_DRAWDDARROWS
);
1971 SendMessageW(hFormatBarWnd
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(height
, height
));
1973 AddButton(hFormatBarWnd
, 0, ID_FORMAT_BOLD
);
1974 AddButton(hFormatBarWnd
, 1, ID_FORMAT_ITALIC
);
1975 AddButton(hFormatBarWnd
, 2, ID_FORMAT_UNDERLINE
);
1976 AddButton(hFormatBarWnd
, 3, ID_FORMAT_COLOR
);
1977 AddSeparator(hFormatBarWnd
);
1978 AddButton(hFormatBarWnd
, 4, ID_ALIGN_LEFT
);
1979 AddButton(hFormatBarWnd
, 5, ID_ALIGN_CENTER
);
1980 AddButton(hFormatBarWnd
, 6, ID_ALIGN_RIGHT
);
1981 AddSeparator(hFormatBarWnd
);
1982 AddButtonStyle(hFormatBarWnd
, 7, ID_BULLETONOFF
, BTNS_DROPDOWN
);
1984 SendMessageW(hFormatBarWnd
, TB_AUTOSIZE
, 0, 0);
1986 rbb
.hwndChild
= hFormatBarWnd
;
1987 rbb
.wID
= BANDID_FORMATBAR
;
1989 SendMessageW(hReBarWnd
, RB_INSERTBANDW
, -1, (LPARAM
)&rbb
);
1991 hRulerWnd
= CreateWindowExW(0, WC_STATICW
, NULL
, WS_VISIBLE
| WS_CHILD
,
1992 0, 0, 200, 10, hReBarWnd
, (HMENU
)IDC_RULER
, hInstance
, NULL
);
1995 rbb
.hwndChild
= hRulerWnd
;
1996 rbb
.wID
= BANDID_RULER
;
1997 rbb
.fStyle
|= RBBS_BREAK
;
1999 SendMessageW(hReBarWnd
, RB_INSERTBANDW
, -1, (LPARAM
)&rbb
);
2001 hDLL
= LoadLibraryW(wszRichEditDll
);
2004 MessageBoxWithResStringW(hWnd
, MAKEINTRESOURCEW(STRING_LOAD_RICHED_FAILED
), wszAppTitle
,
2005 MB_OK
| MB_ICONEXCLAMATION
);
2009 hEditorWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, RICHEDIT_CLASS20W
, NULL
,
2010 WS_CHILD
|WS_VISIBLE
|ES_SELECTIONBAR
|ES_MULTILINE
|ES_AUTOVSCROLL
2011 |ES_WANTRETURN
|WS_VSCROLL
|ES_NOHIDESEL
|WS_HSCROLL
,
2012 0, 0, 1000, 100, hWnd
, (HMENU
)IDC_EDITOR
, hInstance
, NULL
);
2014 if (!hEditorWnd
) return -1;
2016 setup_richedit_olecallback(hEditorWnd
);
2017 SetFocus(hEditorWnd
);
2018 SendMessageW(hEditorWnd
, EM_SETEVENTMASK
, 0, ENM_SELCHANGE
);
2022 populate_font_list(hFontListWnd
);
2023 populate_size_list(hSizeListWnd
);
2025 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
2027 ID_FINDMSGSTRING
= RegisterWindowMessageW(FINDMSGSTRINGW
);
2029 registry_read_filelist(hWnd
);
2030 registry_read_formatopts_all(barState
, wordWrap
);
2031 registry_read_options();
2032 DragAcceptFiles(hWnd
, TRUE
);
2037 static LRESULT
OnUser( HWND hWnd
)
2039 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2040 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
2041 HWND hwndToolBar
= GetDlgItem(hwndReBar
, IDC_TOOLBAR
);
2042 HWND hwndFormatBar
= GetDlgItem(hwndReBar
, IDC_FORMATBAR
);
2048 ZeroMemory(&fmt
, sizeof(fmt
));
2049 fmt
.cbSize
= sizeof(fmt
);
2051 ZeroMemory(&pf
, sizeof(pf
));
2052 pf
.cbSize
= sizeof(pf
);
2054 gt
.flags
= GTL_NUMCHARS
;
2057 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_FIND
,
2058 SendMessageW(hwndEditor
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0) ? 1 : 0);
2060 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, TRUE
, (LPARAM
)&fmt
);
2062 SendMessageW(hwndEditor
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
2063 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_UNDO
,
2064 SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0));
2065 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_REDO
,
2066 SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0));
2067 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_CUT
, from
== to
? 0 : 1);
2068 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_COPY
, from
== to
? 0 : 1);
2070 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_BOLD
, (fmt
.dwMask
& CFM_BOLD
) &&
2071 (fmt
.dwEffects
& CFE_BOLD
));
2072 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_BOLD
, !(fmt
.dwMask
& CFM_BOLD
));
2073 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_ITALIC
, (fmt
.dwMask
& CFM_ITALIC
) &&
2074 (fmt
.dwEffects
& CFE_ITALIC
));
2075 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_ITALIC
, !(fmt
.dwMask
& CFM_ITALIC
));
2076 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_UNDERLINE
, (fmt
.dwMask
& CFM_UNDERLINE
) &&
2077 (fmt
.dwEffects
& CFE_UNDERLINE
));
2078 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_UNDERLINE
, !(fmt
.dwMask
& CFM_UNDERLINE
));
2080 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2081 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_LEFT
, (pf
.wAlignment
== PFA_LEFT
));
2082 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_CENTER
, (pf
.wAlignment
== PFA_CENTER
));
2083 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_RIGHT
, (pf
.wAlignment
== PFA_RIGHT
));
2085 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_BULLETONOFF
, pf
.wNumbering
!= 0);
2089 static LRESULT
OnNotify( HWND hWnd
, LPARAM lParam
)
2091 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2092 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
2093 NMHDR
*pHdr
= (NMHDR
*)lParam
;
2094 HWND hwndFontList
= GetDlgItem(hwndReBar
, IDC_FONTLIST
);
2095 HWND hwndSizeList
= GetDlgItem(hwndReBar
, IDC_SIZELIST
);
2096 HWND hwndFormatBar
= GetDlgItem(hwndReBar
, IDC_FORMATBAR
);
2098 if (pHdr
->hwndFrom
== hwndFontList
|| pHdr
->hwndFrom
== hwndSizeList
)
2100 if (pHdr
->code
== CBEN_ENDEDITW
)
2102 NMCBEENDEDITW
*endEdit
= (NMCBEENDEDITW
*)lParam
;
2103 if(pHdr
->hwndFrom
== hwndFontList
)
2105 on_fontlist_modified(endEdit
->szText
);
2106 } else if (pHdr
->hwndFrom
== hwndSizeList
)
2108 on_sizelist_modified(hwndSizeList
,endEdit
->szText
);
2114 if (pHdr
->hwndFrom
== hwndFormatBar
)
2116 if (pHdr
->code
== TBN_DROPDOWN
)
2118 NMTOOLBARW
*tb_notify
= (NMTOOLBARW
*)lParam
;
2119 HMENU menu
= GetMenu( hWnd
);
2124 if (!menu
) return 0;
2125 info
.cbSize
= sizeof(info
);
2126 info
.fMask
= MIIM_SUBMENU
;
2127 GetMenuItemInfoW( menu
, ID_LISTMENU
, FALSE
, &info
);
2128 if (!info
.hSubMenu
) return 0;
2130 SendMessageW( tb_notify
->hdr
.hwndFrom
, TB_GETRECT
, (WPARAM
)tb_notify
->iItem
, (LPARAM
)&rc
);
2131 MapWindowPoints( tb_notify
->hdr
.hwndFrom
, HWND_DESKTOP
, (LPPOINT
)&rc
, 2 );
2133 params
.cbSize
= sizeof(params
);
2134 params
.rcExclude
= rc
;
2135 TrackPopupMenuEx( info
.hSubMenu
,
2136 TPM_LEFTALIGN
| TPM_LEFTBUTTON
| TPM_VERTICAL
,
2137 rc
.left
, rc
.bottom
, hWnd
, ¶ms
);
2143 if (pHdr
->hwndFrom
== hwndEditor
)
2145 if (pHdr
->code
== EN_SELCHANGE
)
2147 SELCHANGE
*pSC
= (SELCHANGE
*)lParam
;
2152 sprintf( buf
,"selection = %ld..%ld, line count=%Id",
2153 pSC
->chrg
.cpMin
, pSC
->chrg
.cpMax
,
2154 SendMessageW(hwndEditor
, EM_GETLINECOUNT
, 0, 0));
2155 SetWindowTextA(GetDlgItem(hWnd
, IDC_STATUSBAR
), buf
);
2156 SendMessageW(hWnd
, WM_USER
, 0, 0);
2163 /* Copied from dlls/comdlg32/fontdlg.c */
2164 static const COLORREF textcolors
[]=
2166 0x00000000L
,0x00000080L
,0x00008000L
,0x00008080L
,
2167 0x00800000L
,0x00800080L
,0x00808000L
,0x00808080L
,
2168 0x00c0c0c0L
,0x000000ffL
,0x0000ff00L
,0x0000ffffL
,
2169 0x00ff0000L
,0x00ff00ffL
,0x00ffff00L
,0x00FFFFFFL
2172 static LRESULT
OnCommand( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
2174 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2175 static FINDREPLACEW findreplace
;
2177 if ((HWND
)lParam
== hwndEditor
)
2180 switch(LOWORD(wParam
))
2184 PostMessageW(hWnd
, WM_CLOSE
, 0, 0);
2189 HINSTANCE hInstance
= GetModuleHandleW(0);
2190 int ret
= DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_NEWFILE
), hWnd
, newfile_proc
);
2192 if(ret
!= ID_NEWFILE_ABORT
)
2194 if(prompt_save_changes())
2199 wszFileName
[0] = '\0';
2203 st
.flags
= ST_DEFAULT
;
2205 SendMessageW(hEditorWnd
, EM_SETTEXTEX
, (WPARAM
)&st
, 0);
2207 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
2208 set_fileformat(ret
);
2222 DoSaveFile(wszFileName
, fileFormat
);
2227 case ID_FILE_SAVEAS
:
2231 case ID_FILE_RECENT1
:
2232 case ID_FILE_RECENT2
:
2233 case ID_FILE_RECENT3
:
2234 case ID_FILE_RECENT4
:
2236 HMENU hMenu
= GetMenu(hWnd
);
2239 mi
.cbSize
= sizeof(MENUITEMINFOW
);
2240 mi
.fMask
= MIIM_DATA
;
2241 if(GetMenuItemInfoW(hMenu
, LOWORD(wParam
), FALSE
, &mi
))
2242 DoOpenFile((LPWSTR
)mi
.dwItemData
);
2247 dialog_find(&findreplace
, FALSE
);
2251 handle_findmsg(&findreplace
);
2255 dialog_find(&findreplace
, TRUE
);
2258 case ID_FONTSETTINGS
:
2259 dialog_choose_font();
2263 dialog_print(hWnd
, wszFileName
);
2264 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
2267 case ID_PRINT_QUICK
:
2268 print_quick(hMainWnd
, wszFileName
);
2269 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
2274 int index
= reg_formatindex(fileFormat
);
2275 DWORD tmp
= barState
[index
];
2276 barState
[index
] = 1 << BANDID_STATUSBAR
;
2278 barState
[index
] = tmp
;
2279 ShowWindow(hEditorWnd
, FALSE
);
2281 init_preview(hWnd
, wszFileName
);
2283 SetMenu(hWnd
, NULL
);
2284 InvalidateRect(0, 0, TRUE
);
2289 dialog_printsetup(hWnd
);
2290 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
2293 case ID_FORMAT_BOLD
:
2294 case ID_FORMAT_ITALIC
:
2295 case ID_FORMAT_UNDERLINE
:
2298 int effects
= CFE_BOLD
;
2300 ZeroMemory(&fmt
, sizeof(fmt
));
2301 fmt
.cbSize
= sizeof(fmt
);
2302 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
2304 fmt
.dwMask
= CFM_BOLD
;
2306 if (LOWORD(wParam
) == ID_FORMAT_ITALIC
)
2308 effects
= CFE_ITALIC
;
2309 fmt
.dwMask
= CFM_ITALIC
;
2310 } else if (LOWORD(wParam
) == ID_FORMAT_UNDERLINE
)
2312 effects
= CFE_UNDERLINE
;
2313 fmt
.dwMask
= CFM_UNDERLINE
;
2316 fmt
.dwEffects
^= effects
;
2318 SendMessageW(hwndEditor
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
2322 case ID_FORMAT_COLOR
:
2324 HWND hReBarWnd
= GetDlgItem(hWnd
, IDC_REBAR
);
2325 HWND hFormatBarWnd
= GetDlgItem(hReBarWnd
, IDC_FORMATBAR
);
2330 int itemidx
= SendMessageW(hFormatBarWnd
, TB_COMMANDTOINDEX
, ID_FORMAT_COLOR
, 0);
2332 SendMessageW(hFormatBarWnd
, TB_GETITEMRECT
, itemidx
, (LPARAM
)&itemrc
);
2334 pt
.y
= itemrc
.bottom
;
2335 ClientToScreen(hFormatBarWnd
, &pt
);
2336 hPop
= GetSubMenu(hColorPopupMenu
, 0);
2337 mid
= TrackPopupMenu(hPop
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_LEFTBUTTON
|
2338 TPM_RETURNCMD
| TPM_NONOTIFY
,
2339 pt
.x
, pt
.y
, 0, hWnd
, 0);
2340 if (mid
>= ID_COLOR_FIRST
&& mid
<= ID_COLOR_AUTOMATIC
)
2344 ZeroMemory(&fmt
, sizeof(fmt
));
2345 fmt
.cbSize
= sizeof(fmt
);
2346 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
2348 fmt
.dwMask
= CFM_COLOR
;
2350 if (mid
< ID_COLOR_AUTOMATIC
) {
2351 fmt
.crTextColor
= textcolors
[mid
- ID_COLOR_FIRST
];
2352 fmt
.dwEffects
&= ~CFE_AUTOCOLOR
;
2354 fmt
.dwEffects
|= CFE_AUTOCOLOR
;
2357 SendMessageW(hwndEditor
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
2363 PostMessageW(hwndEditor
, WM_CUT
, 0, 0);
2367 PostMessageW(hwndEditor
, WM_COPY
, 0, 0);
2371 PostMessageW(hwndEditor
, WM_PASTE
, 0, 0);
2375 PostMessageW(hwndEditor
, WM_CLEAR
, 0, 0);
2378 case ID_EDIT_SELECTALL
:
2380 CHARRANGE range
= {0, -1};
2381 SendMessageW(hwndEditor
, EM_EXSETSEL
, 0, (LPARAM
)&range
);
2382 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2386 case ID_EDIT_GETTEXT
:
2388 int nLen
= GetWindowTextLengthW(hwndEditor
);
2389 LPWSTR data
= malloc((nLen
+1)*sizeof(WCHAR
) );
2392 GetWindowTextW(hwndEditor
, data
, nLen
+1);
2393 MessageBoxW(NULL
, data
, wszAppTitle
, MB_OK
);
2396 data
= malloc((nLen
+1)*sizeof(WCHAR
));
2398 tr
.chrg
.cpMax
= nLen
;
2399 tr
.lpstrText
= data
;
2400 SendMessageW(hwndEditor
, EM_GETTEXTRANGE
, 0, (LPARAM
)&tr
);
2401 MessageBoxW(NULL
, data
, wszAppTitle
, MB_OK
);
2404 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2408 case ID_EDIT_CHARFORMAT
:
2409 case ID_EDIT_DEFCHARFORMAT
:
2413 ZeroMemory(&cf
, sizeof(cf
));
2414 cf
.cbSize
= sizeof(cf
);
2416 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
,
2417 LOWORD(wParam
) == ID_EDIT_CHARFORMAT
, (LPARAM
)&cf
);
2421 case ID_EDIT_PARAFORMAT
:
2424 ZeroMemory(&pf
, sizeof(pf
));
2425 pf
.cbSize
= sizeof(pf
);
2426 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2430 case ID_EDIT_SELECTIONINFO
:
2432 CHARRANGE range
= {0, -1};
2436 SendMessageW(hwndEditor
, EM_EXGETSEL
, 0, (LPARAM
)&range
);
2437 data
= malloc(sizeof(*data
) * (range
.cpMax
-range
.cpMin
+1));
2438 SendMessageW(hwndEditor
, EM_GETSELTEXT
, 0, (LPARAM
)data
);
2439 sprintf(buf
, "Start = %ld, End = %ld", range
.cpMin
, range
.cpMax
);
2440 MessageBoxA(hWnd
, buf
, "Editor", MB_OK
);
2441 MessageBoxW(hWnd
, data
, wszAppTitle
, MB_OK
);
2443 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2447 case ID_EDIT_READONLY
:
2449 LONG nStyle
= GetWindowLongW(hwndEditor
, GWL_STYLE
);
2450 if (nStyle
& ES_READONLY
)
2451 SendMessageW(hwndEditor
, EM_SETREADONLY
, 0, 0);
2453 SendMessageW(hwndEditor
, EM_SETREADONLY
, 1, 0);
2457 case ID_EDIT_MODIFIED
:
2458 if (SendMessageW(hwndEditor
, EM_GETMODIFY
, 0, 0))
2459 SendMessageW(hwndEditor
, EM_SETMODIFY
, 0, 0);
2461 SendMessageW(hwndEditor
, EM_SETMODIFY
, 1, 0);
2465 SendMessageW(hwndEditor
, EM_UNDO
, 0, 0);
2469 SendMessageW(hwndEditor
, EM_REDO
, 0, 0);
2472 case ID_BULLETONOFF
:
2481 WORD new_number
= LOWORD(wParam
) - ID_BULLET
+ PFN_BULLET
;
2482 pf
.cbSize
= sizeof(pf
);
2483 pf
.dwMask
= PFM_NUMBERING
;
2484 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2486 pf
.dwMask
= PFM_NUMBERING
| PFM_NUMBERINGSTART
| PFM_NUMBERINGSTYLE
| PFM_NUMBERINGTAB
| PFM_OFFSET
| PFM_OFFSETINDENT
;
2488 if(pf
.wNumbering
&& ((pf
.wNumbering
== new_number
) || (LOWORD(wParam
) == ID_BULLETONOFF
)))
2491 pf
.wNumberingStart
= 0;
2492 pf
.wNumberingStyle
= 0;
2493 pf
.wNumberingTab
= 0;
2495 pf
.dxStartIndent
= -360;
2498 pf
.dxStartIndent
= pf
.wNumbering
? 0 : 360;
2500 if (LOWORD(wParam
) == ID_BULLETONOFF
)
2501 pf
.wNumbering
= last_bullet
;
2504 pf
.wNumbering
= new_number
;
2505 last_bullet
= pf
.wNumbering
;
2507 pf
.wNumberingStart
= 1;
2508 pf
.wNumberingStyle
= PFNS_PERIOD
;
2509 pf
.wNumberingTab
= 360;
2513 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
2518 case ID_ALIGN_CENTER
:
2519 case ID_ALIGN_RIGHT
:
2523 pf
.cbSize
= sizeof(pf
);
2524 pf
.dwMask
= PFM_ALIGNMENT
;
2525 switch(LOWORD(wParam
)) {
2526 case ID_ALIGN_LEFT
: pf
.wAlignment
= PFA_LEFT
; break;
2527 case ID_ALIGN_CENTER
: pf
.wAlignment
= PFA_CENTER
; break;
2528 case ID_ALIGN_RIGHT
: pf
.wAlignment
= PFA_RIGHT
; break;
2530 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
2535 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 1, 0);
2539 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 0, RGB(255,255,192));
2542 case ID_TOGGLE_TOOLBAR
:
2543 set_toolbar_state(BANDID_TOOLBAR
, !is_bar_visible(BANDID_TOOLBAR
));
2547 case ID_TOGGLE_FORMATBAR
:
2548 set_toolbar_state(BANDID_FONTLIST
, !is_bar_visible(BANDID_FORMATBAR
));
2549 set_toolbar_state(BANDID_SIZELIST
, !is_bar_visible(BANDID_FORMATBAR
));
2550 set_toolbar_state(BANDID_FORMATBAR
, !is_bar_visible(BANDID_FORMATBAR
));
2554 case ID_TOGGLE_STATUSBAR
:
2555 set_statusbar_state(!is_bar_visible(BANDID_STATUSBAR
));
2559 case ID_TOGGLE_RULER
:
2560 set_toolbar_state(BANDID_RULER
, !is_bar_visible(BANDID_RULER
));
2565 DialogBoxW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_DATETIME
), hWnd
, datetime_proc
);
2569 DialogBoxW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_PARAFORMAT
), hWnd
, paraformat_proc
);
2573 DialogBoxW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_TABSTOPS
), hWnd
, tabstops_proc
);
2580 case ID_VIEWPROPERTIES
:
2581 dialog_viewproperties();
2585 if (HIWORD(wParam
) == CBN_SELENDOK
)
2587 WCHAR buffer
[LF_FACESIZE
];
2588 HWND hwndFontList
= (HWND
)lParam
;
2589 get_comboexlist_selection(hwndFontList
, buffer
, LF_FACESIZE
);
2590 on_fontlist_modified(buffer
);
2595 if (HIWORD(wParam
) == CBN_SELENDOK
)
2597 WCHAR buffer
[MAX_STRING_LEN
+1];
2598 HWND hwndSizeList
= (HWND
)lParam
;
2599 get_comboexlist_selection(hwndSizeList
, buffer
, MAX_STRING_LEN
+1);
2600 on_sizelist_modified(hwndSizeList
, buffer
);
2605 SendMessageW(hwndEditor
, WM_COMMAND
, wParam
, lParam
);
2611 static LRESULT
OnInitPopupMenu( HWND hWnd
, WPARAM wParam
)
2613 HMENU hMenu
= (HMENU
)wParam
;
2614 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2615 HWND hwndStatus
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
2617 int nAlignment
= -1;
2623 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&selFrom
, (LPARAM
)&selTo
);
2624 EnableMenuItem(hMenu
, ID_EDIT_COPY
, (selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
2625 EnableMenuItem(hMenu
, ID_EDIT_CUT
, (selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
2627 pf
.cbSize
= sizeof(PARAFORMAT
);
2628 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2629 CheckMenuItem(hMenu
, ID_EDIT_READONLY
,
2630 (GetWindowLongW(hwndEditor
, GWL_STYLE
) & ES_READONLY
) ? MF_CHECKED
: MF_UNCHECKED
);
2631 CheckMenuItem(hMenu
, ID_EDIT_MODIFIED
,
2632 SendMessageW(hwndEditor
, EM_GETMODIFY
, 0, 0) ? MF_CHECKED
: MF_UNCHECKED
);
2633 if (pf
.dwMask
& PFM_ALIGNMENT
)
2634 nAlignment
= pf
.wAlignment
;
2635 CheckMenuItem(hMenu
, ID_ALIGN_LEFT
, (nAlignment
== PFA_LEFT
) ? MF_CHECKED
: MF_UNCHECKED
);
2636 CheckMenuItem(hMenu
, ID_ALIGN_CENTER
, (nAlignment
== PFA_CENTER
) ? MF_CHECKED
: MF_UNCHECKED
);
2637 CheckMenuItem(hMenu
, ID_ALIGN_RIGHT
, (nAlignment
== PFA_RIGHT
) ? MF_CHECKED
: MF_UNCHECKED
);
2639 CheckMenuItem(hMenu
, ID_BULLET
, ((pf
.wNumbering
== PFN_BULLET
) ? MF_CHECKED
: MF_UNCHECKED
));
2640 CheckMenuItem(hMenu
, ID_NUMBERING
, ((pf
.wNumbering
== PFN_ARABIC
) ? MF_CHECKED
: MF_UNCHECKED
));
2641 CheckMenuItem(hMenu
, ID_LCLETTER
, ((pf
.wNumbering
== PFN_LCLETTER
) ? MF_CHECKED
: MF_UNCHECKED
));
2642 CheckMenuItem(hMenu
, ID_UCLETTER
, ((pf
.wNumbering
== PFN_UCLETTER
) ? MF_CHECKED
: MF_UNCHECKED
));
2643 CheckMenuItem(hMenu
, ID_LCROMAN
, ((pf
.wNumbering
== PFN_LCROMAN
) ? MF_CHECKED
: MF_UNCHECKED
));
2644 CheckMenuItem(hMenu
, ID_UCROMAN
, ((pf
.wNumbering
== PFN_UCROMAN
) ? MF_CHECKED
: MF_UNCHECKED
));
2646 EnableMenuItem(hMenu
, ID_EDIT_UNDO
, SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0) ?
2647 MF_ENABLED
: MF_GRAYED
);
2648 EnableMenuItem(hMenu
, ID_EDIT_REDO
, SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0) ?
2649 MF_ENABLED
: MF_GRAYED
);
2651 CheckMenuItem(hMenu
, ID_TOGGLE_TOOLBAR
, is_bar_visible(BANDID_TOOLBAR
) ?
2652 MF_CHECKED
: MF_UNCHECKED
);
2654 CheckMenuItem(hMenu
, ID_TOGGLE_FORMATBAR
, is_bar_visible(BANDID_FORMATBAR
) ?
2655 MF_CHECKED
: MF_UNCHECKED
);
2657 CheckMenuItem(hMenu
, ID_TOGGLE_STATUSBAR
, IsWindowVisible(hwndStatus
) ?
2658 MF_CHECKED
: MF_UNCHECKED
);
2660 CheckMenuItem(hMenu
, ID_TOGGLE_RULER
, is_bar_visible(BANDID_RULER
) ? MF_CHECKED
: MF_UNCHECKED
);
2662 gt
.flags
= GTL_NUMCHARS
;
2664 textLength
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
2665 EnableMenuItem(hMenu
, ID_FIND
, textLength
? MF_ENABLED
: MF_GRAYED
);
2667 mi
.cbSize
= sizeof(mi
);
2668 mi
.fMask
= MIIM_DATA
;
2670 GetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
2672 EnableMenuItem(hMenu
, ID_FIND_NEXT
, (textLength
&& mi
.dwItemData
) ? MF_ENABLED
: MF_GRAYED
);
2674 EnableMenuItem(hMenu
, ID_REPLACE
, textLength
? MF_ENABLED
: MF_GRAYED
);
2679 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
2681 int nStatusSize
= 0;
2683 HWND hwndEditor
= preview_isactive() ? GetDlgItem(hWnd
, IDC_PREVIEW
) : GetDlgItem(hWnd
, IDC_EDITOR
);
2684 HWND hwndStatusBar
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
2685 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
2686 HWND hRulerWnd
= GetDlgItem(hwndReBar
, IDC_RULER
);
2687 int rebarHeight
= 0;
2691 SendMessageW(hwndStatusBar
, WM_SIZE
, 0, 0);
2692 if (IsWindowVisible(hwndStatusBar
))
2694 GetClientRect(hwndStatusBar
, &rc
);
2695 nStatusSize
= rc
.bottom
- rc
.top
;
2703 rebarHeight
= SendMessageW(hwndReBar
, RB_GETBARHEIGHT
, 0, 0);
2705 MoveWindow(hwndReBar
, 0, 0, LOWORD(lParam
), rebarHeight
, TRUE
);
2709 GetClientRect(hWnd
, &rc
);
2710 MoveWindow(hwndEditor
, 0, rebarHeight
, rc
.right
, rc
.bottom
-nStatusSize
-rebarHeight
, TRUE
);
2713 redraw_ruler(hRulerWnd
);
2715 return DefWindowProcW(hWnd
, WM_SIZE
, wParam
, lParam
);
2718 static LRESULT CALLBACK
WndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2720 if(msg
== ID_FINDMSGSTRING
)
2721 return handle_findmsg((LPFINDREPLACEW
)lParam
);
2726 return OnCreate( hWnd
);
2729 return OnUser( hWnd
);
2732 return OnNotify( hWnd
, lParam
);
2735 if(preview_isactive())
2737 return preview_command( hWnd
, wParam
);
2740 return OnCommand( hWnd
, wParam
, lParam
);
2747 if(preview_isactive())
2750 } else if(prompt_save_changes())
2752 registry_set_options(hMainWnd
);
2753 registry_set_formatopts_all(barState
, wordWrap
);
2760 SetFocus(GetDlgItem(hWnd
, IDC_EDITOR
));
2763 case WM_INITMENUPOPUP
:
2764 return OnInitPopupMenu( hWnd
, wParam
);
2767 return OnSize( hWnd
, wParam
, lParam
);
2769 case WM_CONTEXTMENU
:
2770 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2774 WCHAR file
[MAX_PATH
];
2775 DragQueryFileW((HDROP
)wParam
, 0, file
, MAX_PATH
);
2776 DragFinish((HDROP
)wParam
);
2778 if(prompt_save_changes())
2783 if(!preview_isactive())
2784 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2787 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2793 int CALLBACK
WinMain(HINSTANCE hInstance
, HINSTANCE hOldInstance
, LPSTR szCmdParagraph
, int nCmdShow
)
2795 INITCOMMONCONTROLSEX classes
= {8, ICC_BAR_CLASSES
|ICC_COOL_CLASSES
|ICC_USEREX_CLASSES
};
2800 UINT_PTR hPrevRulerProc
;
2807 static const WCHAR wszAccelTable
[] = {'M','A','I','N','A','C','C','E','L',
2808 'T','A','B','L','E','\0'};
2810 InitCommonControlsEx(&classes
);
2812 hAccel
= LoadAcceleratorsW(hInstance
, wszAccelTable
);
2814 wc
.cbSize
= sizeof(wc
);
2816 wc
.lpfnWndProc
= WndProc
;
2819 wc
.hInstance
= hInstance
;
2820 wc
.hIcon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_WORDPAD
));
2821 wc
.hIconSm
= LoadImageW(hInstance
, MAKEINTRESOURCEW(IDI_WORDPAD
), IMAGE_ICON
,
2822 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), LR_SHARED
);
2823 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_IBEAM
);
2824 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
2825 wc
.lpszMenuName
= MAKEINTRESOURCEW(IDM_MAINMENU
);
2826 wc
.lpszClassName
= wszMainWndClass
;
2827 RegisterClassExW(&wc
);
2830 wc
.lpfnWndProc
= preview_proc
;
2833 wc
.hInstance
= hInstance
;
2836 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_IBEAM
);
2837 wc
.hbrBackground
= NULL
;
2838 wc
.lpszMenuName
= NULL
;
2839 wc
.lpszClassName
= wszPreviewWndClass
;
2840 RegisterClassExW(&wc
);
2842 registry_read_winrect(&rc
);
2843 monitor
= MonitorFromRect(&rc
, MONITOR_DEFAULTTOPRIMARY
);
2844 info
.cbSize
= sizeof(info
);
2845 GetMonitorInfoW(monitor
, &info
);
2849 IntersectRect(&info
.rcWork
, &info
.rcWork
, &rc
);
2850 if (IsRectEmpty(&info
.rcWork
))
2851 x
= y
= CW_USEDEFAULT
;
2853 hMainWnd
= CreateWindowExW(0, wszMainWndClass
, wszAppTitle
, WS_CLIPCHILDREN
|WS_OVERLAPPEDWINDOW
,
2854 x
, y
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, NULL
, NULL
, hInstance
, NULL
);
2855 registry_read_maximized(&bMaximized
);
2856 if ((nCmdShow
== SW_SHOWNORMAL
|| nCmdShow
== SW_SHOWDEFAULT
)
2858 nCmdShow
= SW_SHOWMAXIMIZED
;
2859 ShowWindow(hMainWnd
, nCmdShow
);
2863 set_fileformat(SF_RTF
);
2864 hColorPopupMenu
= LoadMenuW(hInstance
, MAKEINTRESOURCEW(IDM_COLOR_POPUP
));
2865 get_default_printer_opts();
2866 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
2868 hRulerWnd
= GetDlgItem(GetDlgItem(hMainWnd
, IDC_REBAR
), IDC_RULER
);
2869 SendMessageW(GetDlgItem(hMainWnd
, IDC_EDITOR
), EM_POSFROMCHAR
, (WPARAM
)&EditPoint
, 0);
2870 hPrevRulerProc
= SetWindowLongPtrW(hRulerWnd
, GWLP_WNDPROC
, (UINT_PTR
)ruler_proc
);
2871 SendMessageW(hRulerWnd
, WM_USER
, (WPARAM
)&EditPoint
, hPrevRulerProc
);
2873 HandleCommandLine(GetCommandLineW());
2875 while(GetMessageW(&msg
,0,0,0))
2877 if (IsDialogMessageW(hFindWnd
, &msg
))
2880 if (TranslateAcceleratorW(hMainWnd
, hAccel
, &msg
))
2882 TranslateMessage(&msg
);
2883 DispatchMessageW(&msg
);
2884 if (!PeekMessageW(&msg
, 0, 0, 0, PM_NOREMOVE
))
2885 SendMessageW(hMainWnd
, WM_USER
, 0, 0);