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
23 #define _WIN32_IE 0x0400
41 #ifdef NONAMELESSUNION
52 static const WCHAR xszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
54 static const WCHAR wszRichEditClass
[] = {'R','I','C','H','E','D','I','T','2','0','W',0};
55 static const WCHAR wszMainWndClass
[] = {'W','O','R','D','P','A','D','T','O','P',0};
56 static const WCHAR wszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
58 static const WCHAR stringFormat
[] = {'%','2','d','\0'};
61 static HWND hEditorWnd
;
63 static HMENU hPopupMenu
;
65 static UINT ID_FINDMSGSTRING
;
67 static DWORD wordWrap
[2];
68 static DWORD barState
[2];
69 static WPARAM fileFormat
= SF_RTF
;
71 static WCHAR wszFileName
[MAX_PATH
];
72 static WCHAR wszFilter
[MAX_STRING_LEN
*4+6*3+5];
73 static WCHAR wszDefaultFileName
[MAX_STRING_LEN
];
74 static WCHAR wszSaveChanges
[MAX_STRING_LEN
];
75 static WCHAR units_cmW
[MAX_STRING_LEN
];
77 static char units_cmA
[MAX_STRING_LEN
];
79 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
81 /* Load string resources */
82 static void DoLoadStrings(void)
85 static const WCHAR files_rtf
[] = {'*','.','r','t','f','\0'};
86 static const WCHAR files_txt
[] = {'*','.','t','x','t','\0'};
87 static const WCHAR files_all
[] = {'*','.','*','\0'};
89 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
91 LoadStringW(hInstance
, STRING_RICHTEXT_FILES_RTF
, p
, MAX_STRING_LEN
);
93 lstrcpyW(p
, files_rtf
);
95 LoadStringW(hInstance
, STRING_TEXT_FILES_TXT
, p
, MAX_STRING_LEN
);
97 lstrcpyW(p
, files_txt
);
99 LoadStringW(hInstance
, STRING_TEXT_FILES_UNICODE_TXT
, p
, MAX_STRING_LEN
);
100 p
+= lstrlenW(p
) + 1;
101 lstrcpyW(p
, files_txt
);
102 p
+= lstrlenW(p
) + 1;
103 LoadStringW(hInstance
, STRING_ALL_FILES
, p
, MAX_STRING_LEN
);
104 p
+= lstrlenW(p
) + 1;
105 lstrcpyW(p
, files_all
);
106 p
+= lstrlenW(p
) + 1;
109 p
= wszDefaultFileName
;
110 LoadStringW(hInstance
, STRING_DEFAULT_FILENAME
, p
, MAX_STRING_LEN
);
113 LoadStringW(hInstance
, STRING_PROMPT_SAVE_CHANGES
, p
, MAX_STRING_LEN
);
115 LoadStringA(hInstance
, STRING_UNITS_CM
, units_cmA
, MAX_STRING_LEN
);
116 LoadStringW(hInstance
, STRING_UNITS_CM
, units_cmW
, MAX_STRING_LEN
);
119 static void AddButton(HWND hwndToolBar
, int nImage
, int nCommand
)
123 ZeroMemory(&button
, sizeof(button
));
124 button
.iBitmap
= nImage
;
125 button
.idCommand
= nCommand
;
126 button
.fsState
= TBSTATE_ENABLED
;
127 button
.fsStyle
= TBSTYLE_BUTTON
;
130 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
133 static void AddSeparator(HWND hwndToolBar
)
137 ZeroMemory(&button
, sizeof(button
));
139 button
.idCommand
= 0;
141 button
.fsStyle
= TBSTYLE_SEP
;
144 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
147 static DWORD CALLBACK
stream_in(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
149 HANDLE hFile
= (HANDLE
)cookie
;
152 if(!ReadFile(hFile
, buffer
, cb
, &read
, 0))
160 static DWORD CALLBACK
stream_out(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
164 HANDLE hFile
= (HANDLE
)cookie
;
166 ret
= WriteFile(hFile
, buffer
, cb
, &written
, 0);
168 if(!ret
|| (cb
!= written
))
176 LPWSTR
file_basename(LPWSTR path
)
178 LPWSTR pos
= path
+ lstrlenW(path
);
182 if(*pos
== '\\' || *pos
== '/')
192 static void set_caption(LPCWSTR wszNewFileName
)
194 static const WCHAR wszSeparator
[] = {' ','-',' '};
199 wszNewFileName
= wszDefaultFileName
;
201 wszNewFileName
= file_basename((LPWSTR
)wszNewFileName
);
203 wszCaption
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
204 lstrlenW(wszNewFileName
)*sizeof(WCHAR
)+sizeof(wszSeparator
)+sizeof(wszAppTitle
));
209 memcpy(wszCaption
, wszNewFileName
, lstrlenW(wszNewFileName
)*sizeof(WCHAR
));
210 length
+= lstrlenW(wszNewFileName
);
211 memcpy(wszCaption
+ length
, wszSeparator
, sizeof(wszSeparator
));
212 length
+= sizeof(wszSeparator
) / sizeof(WCHAR
);
213 memcpy(wszCaption
+ length
, wszAppTitle
, sizeof(wszAppTitle
));
215 SetWindowTextW(hMainWnd
, wszCaption
);
217 HeapFree(GetProcessHeap(), 0, wszCaption
);
220 static BOOL
validate_endptr(LPCSTR endptr
, BOOL units
)
222 if(!endptr
|| !*endptr
)
225 while(*endptr
== ' ')
229 return *endptr
!= '\0';
231 /* FIXME: Allow other units and convert between them */
232 if(!lstrcmpA(endptr
, units_cmA
))
235 return *endptr
!= '\0';
238 static BOOL
number_from_string(LPCWSTR string
, float *num
, BOOL units
)
241 char buffer
[MAX_STRING_LEN
];
242 char *endptr
= buffer
;
244 WideCharToMultiByte(CP_ACP
, 0, string
, -1, buffer
, MAX_STRING_LEN
, NULL
, NULL
);
247 ret
= strtod(buffer
, &endptr
);
249 if((ret
== 0 && errno
!= 0) || endptr
== buffer
|| validate_endptr(endptr
, units
))
259 static void set_size(float size
)
263 ZeroMemory(&fmt
, sizeof(fmt
));
264 fmt
.cbSize
= sizeof(fmt
);
265 fmt
.dwMask
= CFM_SIZE
;
266 fmt
.yHeight
= (int)(size
* 20.0);
267 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
270 static void add_size(HWND hSizeListWnd
, unsigned size
)
273 COMBOBOXEXITEMW cbItem
;
274 cbItem
.mask
= CBEIF_TEXT
;
277 wsprintfW(buffer
, stringFormat
, size
);
278 cbItem
.pszText
= (LPWSTR
)buffer
;
279 SendMessageW(hSizeListWnd
, CBEM_INSERTITEMW
, 0, (LPARAM
)&cbItem
);
282 static void populate_size_list(HWND hSizeListWnd
)
284 HWND hReBarWnd
= GetDlgItem(hMainWnd
, IDC_REBAR
);
285 HWND hFontListWnd
= GetDlgItem(hReBarWnd
, IDC_FONTLIST
);
286 COMBOBOXEXITEMW cbFontItem
;
288 HWND hListEditWnd
= (HWND
)SendMessageW(hSizeListWnd
, CBEM_GETEDITCONTROL
, 0, 0);
289 HDC hdc
= GetDC(hMainWnd
);
290 static const unsigned choices
[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
295 ZeroMemory(&fmt
, sizeof(fmt
));
296 fmt
.cbSize
= sizeof(fmt
);
297 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
299 cbFontItem
.mask
= CBEIF_LPARAM
;
300 cbFontItem
.iItem
= SendMessageW(hFontListWnd
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)fmt
.szFaceName
);
301 SendMessageW(hFontListWnd
, CBEM_GETITEMW
, 0, (LPARAM
)&cbFontItem
);
303 fontStyle
= (DWORD
)LOWORD(cbFontItem
.lParam
);
305 SendMessageW(hSizeListWnd
, CB_RESETCONTENT
, 0, 0);
307 if((fontStyle
& RASTER_FONTTYPE
) && cbFontItem
.iItem
)
309 add_size(hSizeListWnd
, (BYTE
)MulDiv(HIWORD(cbFontItem
.lParam
), 72,
310 GetDeviceCaps(hdc
, LOGPIXELSY
)));
313 for(i
= 0; i
< sizeof(choices
)/sizeof(choices
[0]); i
++)
314 add_size(hSizeListWnd
, choices
[i
]);
317 wsprintfW(buffer
, stringFormat
, fmt
.yHeight
/ 20);
318 SendMessageW(hListEditWnd
, WM_SETTEXT
, 0, (LPARAM
)buffer
);
321 static void update_size_list(void)
323 HWND hReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
324 HWND hwndSizeList
= GetDlgItem(hReBar
, IDC_SIZELIST
);
325 HWND hwndSizeListEdit
= (HWND
)SendMessageW(hwndSizeList
, CBEM_GETEDITCONTROL
, 0, 0);
326 WCHAR fontSize
[MAX_STRING_LEN
], sizeBuffer
[MAX_STRING_LEN
];
329 ZeroMemory(&fmt
, sizeof(fmt
));
330 fmt
.cbSize
= sizeof(fmt
);
332 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
334 SendMessageW(hwndSizeListEdit
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)fontSize
);
335 wsprintfW(sizeBuffer
, stringFormat
, fmt
.yHeight
/ 20);
337 if(lstrcmpW(fontSize
, sizeBuffer
))
338 SendMessageW(hwndSizeListEdit
, WM_SETTEXT
, 0, (LPARAM
)sizeBuffer
);
341 static void update_font_list(void)
343 HWND hReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
344 HWND hFontList
= GetDlgItem(hReBar
, IDC_FONTLIST
);
345 HWND hFontListEdit
= (HWND
)SendMessageW(hFontList
, CBEM_GETEDITCONTROL
, 0, 0);
346 WCHAR fontName
[MAX_STRING_LEN
];
349 ZeroMemory(&fmt
, sizeof(fmt
));
350 fmt
.cbSize
= sizeof(fmt
);
352 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
353 SendMessageW(hFontListEdit
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)fontName
);
355 if(lstrcmpW(fontName
, fmt
.szFaceName
))
357 SendMessageW(hFontListEdit
, WM_SETTEXT
, 0, (LPARAM
)fmt
.szFaceName
);
358 populate_size_list(GetDlgItem(hReBar
, IDC_SIZELIST
));
365 static void clear_formatting(void)
369 pf
.cbSize
= sizeof(pf
);
370 pf
.dwMask
= PFM_ALIGNMENT
;
371 pf
.wAlignment
= PFA_LEFT
;
372 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
375 static int fileformat_number(WPARAM format
)
379 if(format
== SF_TEXT
)
382 } else if (format
== (SF_TEXT
| SF_UNICODE
))
389 static WPARAM
fileformat_flags(int format
)
391 WPARAM flags
[] = { SF_RTF
, SF_TEXT
, SF_TEXT
| SF_UNICODE
};
393 return flags
[format
];
396 static void set_font(LPCWSTR wszFaceName
)
398 HWND hReBarWnd
= GetDlgItem(hMainWnd
, IDC_REBAR
);
399 HWND hSizeListWnd
= GetDlgItem(hReBarWnd
, IDC_SIZELIST
);
400 HWND hFontListWnd
= GetDlgItem(hReBarWnd
, IDC_FONTLIST
);
401 HWND hFontListEditWnd
= (HWND
)SendMessageW(hFontListWnd
, CBEM_GETEDITCONTROL
, 0, 0);
404 ZeroMemory(&fmt
, sizeof(fmt
));
406 fmt
.cbSize
= sizeof(fmt
);
407 fmt
.dwMask
= CFM_FACE
;
409 lstrcpyW(fmt
.szFaceName
, wszFaceName
);
411 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
413 populate_size_list(hSizeListWnd
);
415 SendMessageW(hFontListEditWnd
, WM_SETTEXT
, 0, (LPARAM
)(LPWSTR
)wszFaceName
);
418 static void set_default_font(void)
420 static const WCHAR richTextFont
[] = {'T','i','m','e','s',' ','N','e','w',' ',
421 'R','o','m','a','n',0};
422 static const WCHAR plainTextFont
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
426 ZeroMemory(&fmt
, sizeof(fmt
));
428 fmt
.cbSize
= sizeof(fmt
);
429 fmt
.dwMask
= CFM_FACE
| CFM_BOLD
| CFM_ITALIC
| CFM_UNDERLINE
;
432 if(fileFormat
& SF_RTF
)
435 font
= plainTextFont
;
437 lstrcpyW(fmt
.szFaceName
, font
);
439 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_DEFAULT
, (LPARAM
)&fmt
);
442 static void add_font(LPCWSTR fontName
, DWORD fontType
, HWND hListWnd
, NEWTEXTMETRICEXW
*ntmc
)
444 COMBOBOXEXITEMW cbItem
;
445 WCHAR buffer
[MAX_PATH
];
448 cbItem
.mask
= CBEIF_TEXT
;
449 cbItem
.pszText
= buffer
;
450 cbItem
.cchTextMax
= MAX_STRING_LEN
;
453 while(SendMessageW(hListWnd
, CBEM_GETITEMW
, 0, (LPARAM
)&cbItem
))
455 if(lstrcmpiW(cbItem
.pszText
, fontName
) <= 0)
460 cbItem
.pszText
= HeapAlloc( GetProcessHeap(), 0, (lstrlenW(fontName
) + 1)*sizeof(WCHAR
) );
461 lstrcpyW( cbItem
.pszText
, fontName
);
463 cbItem
.mask
|= CBEIF_LPARAM
;
464 if(fontType
& RASTER_FONTTYPE
)
465 fontHeight
= ntmc
->ntmTm
.tmHeight
- ntmc
->ntmTm
.tmInternalLeading
;
467 cbItem
.lParam
= MAKELONG(fontType
,fontHeight
);
468 SendMessageW(hListWnd
, CBEM_INSERTITEMW
, 0, (LPARAM
)&cbItem
);
469 HeapFree( GetProcessHeap(), 0, cbItem
.pszText
);
472 static void dialog_choose_font(void)
477 HDC hDC
= GetDC(hMainWnd
);
479 ZeroMemory(&cf
, sizeof(cf
));
480 cf
.lStructSize
= sizeof(cf
);
481 cf
.hwndOwner
= hMainWnd
;
483 cf
.Flags
= CF_SCREENFONTS
| CF_NOSCRIPTSEL
| CF_INITTOLOGFONTSTRUCT
| CF_EFFECTS
;
485 ZeroMemory(&fmt
, sizeof(fmt
));
486 fmt
.cbSize
= sizeof(fmt
);
488 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
489 lstrcpyW(cf
.lpLogFont
->lfFaceName
, fmt
.szFaceName
);
490 cf
.lpLogFont
->lfItalic
= (fmt
.dwEffects
& CFE_ITALIC
) ? TRUE
: FALSE
;
491 cf
.lpLogFont
->lfWeight
= (fmt
.dwEffects
& CFE_BOLD
) ? FW_BOLD
: FW_NORMAL
;
492 cf
.lpLogFont
->lfUnderline
= (fmt
.dwEffects
& CFE_UNDERLINE
) ? TRUE
: FALSE
;
493 cf
.lpLogFont
->lfStrikeOut
= (fmt
.dwEffects
& CFE_STRIKEOUT
) ? TRUE
: FALSE
;
494 cf
.lpLogFont
->lfHeight
= -MulDiv(fmt
.yHeight
/ 20, GetDeviceCaps(hDC
, LOGPIXELSY
), 72);
495 cf
.rgbColors
= fmt
.crTextColor
;
499 ZeroMemory(&fmt
, sizeof(fmt
));
500 fmt
.cbSize
= sizeof(fmt
);
501 fmt
.dwMask
= CFM_BOLD
| CFM_ITALIC
| CFM_SIZE
| CFM_UNDERLINE
| CFM_STRIKEOUT
| CFM_COLOR
;
502 fmt
.yHeight
= cf
.iPointSize
* 2;
504 if(cf
.nFontType
& BOLD_FONTTYPE
)
505 fmt
.dwEffects
|= CFE_BOLD
;
506 if(cf
.nFontType
& ITALIC_FONTTYPE
)
507 fmt
.dwEffects
|= CFE_ITALIC
;
508 if(cf
.lpLogFont
->lfUnderline
== TRUE
)
509 fmt
.dwEffects
|= CFE_UNDERLINE
;
510 if(cf
.lpLogFont
->lfStrikeOut
== TRUE
)
511 fmt
.dwEffects
|= CFE_STRIKEOUT
;
513 fmt
.crTextColor
= cf
.rgbColors
;
515 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
516 set_font(cf
.lpLogFont
->lfFaceName
);
521 int CALLBACK
enum_font_proc(const LOGFONTW
*lpelfe
, const TEXTMETRICW
*lpntme
,
522 DWORD FontType
, LPARAM lParam
)
524 HWND hListWnd
= (HWND
) lParam
;
526 if(SendMessageW(hListWnd
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)lpelfe
->lfFaceName
) == CB_ERR
)
529 add_font((LPWSTR
)lpelfe
->lfFaceName
, FontType
, hListWnd
, (NEWTEXTMETRICEXW
*)lpntme
);
535 static void populate_font_list(HWND hListWnd
)
537 HDC hdc
= GetDC(hMainWnd
);
539 HWND hListEditWnd
= (HWND
)SendMessageW(hListWnd
, CBEM_GETEDITCONTROL
, 0, 0);
542 fontinfo
.lfCharSet
= DEFAULT_CHARSET
;
543 *fontinfo
.lfFaceName
= '\0';
544 fontinfo
.lfPitchAndFamily
= 0;
546 EnumFontFamiliesExW(hdc
, &fontinfo
, enum_font_proc
,
547 (LPARAM
)hListWnd
, 0);
549 ZeroMemory(&fmt
, sizeof(fmt
));
550 fmt
.cbSize
= sizeof(fmt
);
551 SendMessageW(hEditorWnd
, EM_GETCHARFORMAT
, SCF_DEFAULT
, (LPARAM
)&fmt
);
552 SendMessageW(hListEditWnd
, WM_SETTEXT
, 0, (LPARAM
)fmt
.szFaceName
);
555 static void update_window(void)
559 GetWindowRect(hMainWnd
, &rect
);
561 (void) OnSize(hMainWnd
, SIZE_RESTORED
, MAKELONG(rect
.bottom
, rect
.right
));
564 static BOOL
is_bar_visible(int bandId
)
566 return barState
[reg_formatindex(fileFormat
)] & (1 << bandId
);
569 static void store_bar_state(int bandId
, BOOL show
)
571 int formatIndex
= reg_formatindex(fileFormat
);
574 barState
[formatIndex
] |= (1 << bandId
);
576 barState
[formatIndex
] &= ~(1 << bandId
);
579 static void set_toolbar_state(int bandId
, BOOL show
)
581 HWND hwndReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
583 SendMessageW(hwndReBar
, RB_SHOWBAND
, SendMessageW(hwndReBar
, RB_IDTOINDEX
, bandId
, 0), show
);
585 if(bandId
== BANDID_TOOLBAR
)
587 REBARBANDINFOW rbbinfo
;
588 int index
= SendMessageW(hwndReBar
, RB_IDTOINDEX
, BANDID_FONTLIST
, 0);
590 rbbinfo
.cbSize
= sizeof(rbbinfo
);
591 rbbinfo
.fMask
= RBBIM_STYLE
;
593 SendMessageW(hwndReBar
, RB_GETBANDINFO
, index
, (LPARAM
)&rbbinfo
);
596 rbbinfo
.fStyle
&= ~RBBS_BREAK
;
598 rbbinfo
.fStyle
|= RBBS_BREAK
;
600 SendMessageW(hwndReBar
, RB_SETBANDINFO
, index
, (LPARAM
)&rbbinfo
);
603 if(bandId
== BANDID_TOOLBAR
|| bandId
== BANDID_FORMATBAR
|| bandId
== BANDID_RULER
)
604 store_bar_state(bandId
, show
);
607 static void set_statusbar_state(BOOL show
)
609 HWND hStatusWnd
= GetDlgItem(hMainWnd
, IDC_STATUSBAR
);
611 ShowWindow(hStatusWnd
, show
? SW_SHOW
: SW_HIDE
);
612 store_bar_state(BANDID_STATUSBAR
, show
);
615 static void set_bar_states(void)
617 set_toolbar_state(BANDID_TOOLBAR
, is_bar_visible(BANDID_TOOLBAR
));
618 set_toolbar_state(BANDID_FONTLIST
, is_bar_visible(BANDID_FORMATBAR
));
619 set_toolbar_state(BANDID_SIZELIST
, is_bar_visible(BANDID_FORMATBAR
));
620 set_toolbar_state(BANDID_FORMATBAR
, is_bar_visible(BANDID_FORMATBAR
));
621 set_toolbar_state(BANDID_RULER
, is_bar_visible(BANDID_RULER
));
622 set_statusbar_state(is_bar_visible(BANDID_STATUSBAR
));
627 static void preview_exit(HWND hMainWnd
)
629 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
630 HMENU hMenu
= LoadMenuW(hInstance
, MAKEINTRESOURCEW(IDM_MAINMENU
));
631 HWND hEditorWnd
= GetDlgItem(hMainWnd
, IDC_EDITOR
);
634 ShowWindow(hEditorWnd
, TRUE
);
636 close_preview(hMainWnd
);
638 SetMenu(hMainWnd
, hMenu
);
639 registry_read_filelist(hMainWnd
);
644 static void set_fileformat(WPARAM format
)
647 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
651 hIcon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_TXT
));
653 hIcon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_RTF
));
655 SendMessageW(hMainWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
659 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
662 static void DoOpenFile(LPCWSTR szOpenFileName
)
668 WPARAM format
= SF_TEXT
;
670 hFile
= CreateFileW(szOpenFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
671 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
672 if (hFile
== INVALID_HANDLE_VALUE
)
675 ReadFile(hFile
, fileStart
, 5, &readOut
, NULL
);
676 SetFilePointer(hFile
, 0, NULL
, FILE_BEGIN
);
678 if(readOut
>= 2 && (BYTE
)fileStart
[0] == 0xff && (BYTE
)fileStart
[1] == 0xfe)
680 format
= SF_TEXT
| SF_UNICODE
;
681 SetFilePointer(hFile
, 2, NULL
, FILE_BEGIN
);
682 } else if(readOut
>= 5)
684 static const char header
[] = "{\\rtf";
685 static const BYTE STG_magic
[] = { 0xd0,0xcf,0x11,0xe0 };
687 if(!memcmp(header
, fileStart
, 5))
689 else if (!memcmp(STG_magic
, fileStart
, sizeof(STG_magic
)))
692 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_OLE_STORAGE_NOT_SUPPORTED
), wszAppTitle
,
693 MB_OK
| MB_ICONEXCLAMATION
);
698 es
.dwCookie
= (DWORD_PTR
)hFile
;
699 es
.pfnCallback
= stream_in
;
702 set_fileformat(format
);
703 SendMessageW(hEditorWnd
, EM_STREAMIN
, format
, (LPARAM
)&es
);
707 SetFocus(hEditorWnd
);
709 set_caption(szOpenFileName
);
711 lstrcpyW(wszFileName
, szOpenFileName
);
712 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
713 registry_set_filelist(szOpenFileName
, hMainWnd
);
717 static void DoSaveFile(LPCWSTR wszSaveFileName
, WPARAM format
)
723 hFile
= CreateFileW(wszSaveFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
724 FILE_ATTRIBUTE_NORMAL
, NULL
);
726 if(hFile
== INVALID_HANDLE_VALUE
)
729 if(format
== (SF_TEXT
| SF_UNICODE
))
731 static const BYTE unicode
[] = {0xff,0xfe};
733 WriteFile(hFile
, &unicode
, sizeof(unicode
), &writeOut
, 0);
735 if(writeOut
!= sizeof(unicode
))
739 stream
.dwCookie
= (DWORD_PTR
)hFile
;
740 stream
.pfnCallback
= stream_out
;
742 ret
= SendMessageW(hEditorWnd
, EM_STREAMOUT
, format
, (LPARAM
)&stream
);
746 SetFocus(hEditorWnd
);
751 gt
.flags
= GTL_DEFAULT
;
754 if(SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
758 lstrcpyW(wszFileName
, wszSaveFileName
);
759 set_caption(wszFileName
);
760 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
761 set_fileformat(format
);
764 static void DialogSaveFile(void)
768 WCHAR wszFile
[MAX_PATH
] = {'\0'};
769 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
771 ZeroMemory(&sfn
, sizeof(sfn
));
773 sfn
.lStructSize
= sizeof(sfn
);
774 sfn
.Flags
= OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
;
775 sfn
.hwndOwner
= hMainWnd
;
776 sfn
.lpstrFilter
= wszFilter
;
777 sfn
.lpstrFile
= wszFile
;
778 sfn
.nMaxFile
= MAX_PATH
;
779 sfn
.lpstrDefExt
= wszDefExt
;
780 sfn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
782 while(GetSaveFileNameW(&sfn
))
784 if(fileformat_flags(sfn
.nFilterIndex
-1) != SF_RTF
)
786 if(MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_SAVE_LOSEFORMATTING
),
787 wszAppTitle
, MB_YESNO
| MB_ICONEXCLAMATION
) != IDYES
)
792 DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
797 DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
803 static BOOL
prompt_save_changes(void)
808 gt
.flags
= GTL_NUMCHARS
;
810 if(!SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
814 if(!SendMessageW(hEditorWnd
, EM_GETMODIFY
, 0, 0))
819 LPWSTR displayFileName
;
824 displayFileName
= wszDefaultFileName
;
826 displayFileName
= file_basename(wszFileName
);
828 text
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
829 (lstrlenW(displayFileName
)+lstrlenW(wszSaveChanges
))*sizeof(WCHAR
));
834 wsprintfW(text
, wszSaveChanges
, displayFileName
);
836 ret
= MessageBoxW(hMainWnd
, text
, wszAppTitle
, MB_YESNOCANCEL
| MB_ICONEXCLAMATION
);
838 HeapFree(GetProcessHeap(), 0, text
);
847 DoSaveFile(wszFileName
, fileFormat
);
858 static void DialogOpenFile(void)
862 WCHAR wszFile
[MAX_PATH
] = {'\0'};
863 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
865 ZeroMemory(&ofn
, sizeof(ofn
));
867 ofn
.lStructSize
= sizeof(ofn
);
868 ofn
.Flags
= OFN_HIDEREADONLY
| OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
869 ofn
.hwndOwner
= hMainWnd
;
870 ofn
.lpstrFilter
= wszFilter
;
871 ofn
.lpstrFile
= wszFile
;
872 ofn
.nMaxFile
= MAX_PATH
;
873 ofn
.lpstrDefExt
= wszDefExt
;
874 ofn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
876 if(GetOpenFileNameW(&ofn
))
878 if(prompt_save_changes())
879 DoOpenFile(ofn
.lpstrFile
);
883 static void dialog_about(void)
885 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
886 HICON icon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_WORDPAD
));
887 ShellAboutW(hMainWnd
, wszAppTitle
, 0, icon
);
890 static INT_PTR CALLBACK
formatopts_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
896 LPPROPSHEETPAGEW ps
= (LPPROPSHEETPAGEW
)lParam
;
899 HWND hIdWnd
= GetDlgItem(hWnd
, IDC_PAGEFMT_ID
);
901 sprintf(id
, "%d\n", (int)ps
->lParam
);
902 SetWindowTextA(hIdWnd
, id
);
903 if(wordWrap
[ps
->lParam
] == ID_WORDWRAP_WINDOW
)
904 wrap
= IDC_PAGEFMT_WW
;
905 else if(wordWrap
[ps
->lParam
] == ID_WORDWRAP_MARGIN
)
906 wrap
= IDC_PAGEFMT_WM
;
909 CheckRadioButton(hWnd
, IDC_PAGEFMT_WW
,
910 IDC_PAGEFMT_WM
, wrap
);
912 if(barState
[ps
->lParam
] & (1 << BANDID_TOOLBAR
))
913 CheckDlgButton(hWnd
, IDC_PAGEFMT_TB
, TRUE
);
914 if(barState
[ps
->lParam
] & (1 << BANDID_FORMATBAR
))
915 CheckDlgButton(hWnd
, IDC_PAGEFMT_FB
, TRUE
);
916 if(barState
[ps
->lParam
] & (1 << BANDID_RULER
))
917 CheckDlgButton(hWnd
, IDC_PAGEFMT_RU
, TRUE
);
918 if(barState
[ps
->lParam
] & (1 << BANDID_STATUSBAR
))
919 CheckDlgButton(hWnd
, IDC_PAGEFMT_SB
, TRUE
);
924 switch(LOWORD(wParam
))
928 CheckRadioButton(hWnd
, IDC_PAGEFMT_WW
, IDC_PAGEFMT_WM
,
936 CheckDlgButton(hWnd
, LOWORD(wParam
),
937 !IsDlgButtonChecked(hWnd
, LOWORD(wParam
)));
943 LPNMHDR header
= (LPNMHDR
)lParam
;
944 if(header
->code
== PSN_APPLY
)
946 HWND hIdWnd
= GetDlgItem(hWnd
, IDC_PAGEFMT_ID
);
950 GetWindowTextA(hIdWnd
, sid
, 4);
952 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_WW
))
953 wordWrap
[id
] = ID_WORDWRAP_WINDOW
;
954 else if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_WM
))
955 wordWrap
[id
] = ID_WORDWRAP_MARGIN
;
957 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_TB
))
958 barState
[id
] |= (1 << BANDID_TOOLBAR
);
960 barState
[id
] &= ~(1 << BANDID_TOOLBAR
);
962 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_FB
))
963 barState
[id
] |= (1 << BANDID_FORMATBAR
);
965 barState
[id
] &= ~(1 << BANDID_FORMATBAR
);
967 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_RU
))
968 barState
[id
] |= (1 << BANDID_RULER
);
970 barState
[id
] &= ~(1 << BANDID_RULER
);
972 if(IsDlgButtonChecked(hWnd
, IDC_PAGEFMT_SB
))
973 barState
[id
] |= (1 << BANDID_STATUSBAR
);
975 barState
[id
] &= ~(1 << BANDID_STATUSBAR
);
983 static void dialog_viewproperties(void)
985 PROPSHEETPAGEW psp
[2];
986 PROPSHEETHEADERW psh
;
988 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
989 LPCPROPSHEETPAGEW ppsp
= (LPCPROPSHEETPAGEW
)&psp
;
991 psp
[0].dwSize
= sizeof(PROPSHEETPAGEW
);
992 psp
[0].dwFlags
= PSP_USETITLE
;
993 U(psp
[0]).pszTemplate
= MAKEINTRESOURCEW(IDD_FORMATOPTS
);
994 psp
[0].pfnDlgProc
= formatopts_proc
;
995 psp
[0].hInstance
= hInstance
;
996 psp
[0].lParam
= reg_formatindex(SF_TEXT
);
997 psp
[0].pfnCallback
= NULL
;
998 psp
[0].pszTitle
= MAKEINTRESOURCEW(STRING_VIEWPROPS_TEXT
);
999 for(i
= 1; i
< sizeof(psp
)/sizeof(psp
[0]); i
++)
1001 psp
[i
].dwSize
= psp
[0].dwSize
;
1002 psp
[i
].dwFlags
= psp
[0].dwFlags
;
1003 U(psp
[i
]).pszTemplate
= U(psp
[0]).pszTemplate
;
1004 psp
[i
].pfnDlgProc
= psp
[0].pfnDlgProc
;
1005 psp
[i
].hInstance
= psp
[0].hInstance
;
1006 psp
[i
].lParam
= reg_formatindex(SF_RTF
);
1007 psp
[i
].pfnCallback
= psp
[0].pfnCallback
;
1008 psp
[i
].pszTitle
= MAKEINTRESOURCEW(STRING_VIEWPROPS_RICHTEXT
);
1011 psh
.dwSize
= sizeof(psh
);
1012 psh
.dwFlags
= PSH_USEICONID
| PSH_PROPSHEETPAGE
| PSH_NOAPPLYNOW
;
1013 psh
.hwndParent
= hMainWnd
;
1014 psh
.hInstance
= hInstance
;
1015 psh
.pszCaption
= MAKEINTRESOURCEW(STRING_VIEWPROPS_TITLE
);
1016 psh
.nPages
= sizeof(psp
)/sizeof(psp
[0]);
1017 U3(psh
).ppsp
= ppsp
;
1018 U(psh
).pszIcon
= MAKEINTRESOURCEW(IDI_WORDPAD
);
1020 if(fileFormat
& SF_RTF
)
1021 U2(psh
).nStartPage
= 1;
1023 U2(psh
).nStartPage
= 0;
1024 PropertySheetW(&psh
);
1026 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
1029 static void HandleCommandLine(LPWSTR cmdline
)
1034 /* skip white space */
1035 while (*cmdline
== ' ') cmdline
++;
1037 /* skip executable name */
1038 delimiter
= (*cmdline
== '"' ? '"' : ' ');
1040 if (*cmdline
== delimiter
) cmdline
++;
1041 while (*cmdline
&& *cmdline
!= delimiter
) cmdline
++;
1042 if (*cmdline
== delimiter
) cmdline
++;
1044 while (*cmdline
== ' ' || *cmdline
== '-' || *cmdline
== '/')
1048 if (*cmdline
++ == ' ') continue;
1051 if (option
) cmdline
++;
1052 while (*cmdline
== ' ') cmdline
++;
1065 /* file name is passed on the command line */
1066 if (cmdline
[0] == '"')
1069 cmdline
[lstrlenW(cmdline
) - 1] = 0;
1071 DoOpenFile(cmdline
);
1072 InvalidateRect(hMainWnd
, NULL
, FALSE
);
1076 MessageBox(hMainWnd
, "Printing not implemented", "WordPad", MB_OK
);
1079 static LRESULT
handle_findmsg(LPFINDREPLACEW pFr
)
1081 if(pFr
->Flags
& FR_DIALOGTERM
)
1084 pFr
->Flags
= FR_FINDNEXT
;
1088 if(pFr
->Flags
& FR_FINDNEXT
|| pFr
->Flags
& FR_REPLACE
|| pFr
->Flags
& FR_REPLACEALL
)
1090 DWORD flags
= FR_DOWN
;
1092 static CHARRANGE cr
;
1097 HMENU hMenu
= GetMenu(hMainWnd
);
1100 mi
.cbSize
= sizeof(mi
);
1101 mi
.fMask
= MIIM_DATA
;
1103 SetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
1105 gt
.flags
= GTL_NUMCHARS
;
1108 length
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
1110 if(pFr
->lCustData
== -1)
1112 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&startPos
, (LPARAM
)&end
);
1113 cr
.cpMin
= startPos
;
1114 pFr
->lCustData
= startPos
;
1116 if(cr
.cpMin
== length
)
1120 startPos
= pFr
->lCustData
;
1123 if(cr
.cpMax
> length
)
1131 ft
.lpstrText
= pFr
->lpstrFindWhat
;
1133 if(pFr
->Flags
& FR_MATCHCASE
)
1134 flags
|= FR_MATCHCASE
;
1135 if(pFr
->Flags
& FR_WHOLEWORD
)
1136 flags
|= FR_WHOLEWORD
;
1138 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTW
, (WPARAM
)flags
, (LPARAM
)&ft
);
1142 if(cr
.cpMax
== length
&& cr
.cpMax
!= startPos
)
1144 ft
.chrg
.cpMin
= cr
.cpMin
= 0;
1145 ft
.chrg
.cpMax
= cr
.cpMax
= startPos
;
1147 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTW
, (WPARAM
)flags
, (LPARAM
)&ft
);
1153 pFr
->lCustData
= -1;
1154 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED
), wszAppTitle
,
1155 MB_OK
| MB_ICONASTERISK
);
1158 end
= ret
+ lstrlenW(pFr
->lpstrFindWhat
);
1160 SendMessageW(hEditorWnd
, EM_SETSEL
, (WPARAM
)ret
, (LPARAM
)end
);
1161 SendMessageW(hEditorWnd
, EM_SCROLLCARET
, 0, 0);
1163 if(pFr
->Flags
& FR_REPLACE
|| pFr
->Flags
& FR_REPLACEALL
)
1164 SendMessageW(hEditorWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)pFr
->lpstrReplaceWith
);
1166 if(pFr
->Flags
& FR_REPLACEALL
)
1167 handle_findmsg(pFr
);
1174 static void dialog_find(LPFINDREPLACEW fr
, BOOL replace
)
1176 static WCHAR findBuffer
[MAX_STRING_LEN
];
1178 ZeroMemory(fr
, sizeof(FINDREPLACEW
));
1179 fr
->lStructSize
= sizeof(FINDREPLACEW
);
1180 fr
->hwndOwner
= hMainWnd
;
1181 fr
->Flags
= FR_HIDEUPDOWN
;
1182 fr
->lpstrFindWhat
= findBuffer
;
1184 fr
->wFindWhatLen
= MAX_STRING_LEN
*sizeof(WCHAR
);
1187 hFindWnd
= ReplaceTextW(fr
);
1189 hFindWnd
= FindTextW(fr
);
1192 static int current_units_to_twips(float number
)
1194 int twips
= (int)(number
* TWIPS_PER_CM
);
1198 static void append_current_units(LPWSTR buffer
)
1200 static const WCHAR space
[] = {' '};
1201 lstrcatW(buffer
, space
);
1202 lstrcatW(buffer
, units_cmW
);
1205 static void number_with_units(LPWSTR buffer
, int number
)
1207 float converted
= (float)number
/ TWIPS_PER_CM
;
1208 char string
[MAX_STRING_LEN
];
1210 sprintf(string
, "%.2f ", converted
);
1211 lstrcatA(string
, units_cmA
);
1212 MultiByteToWideChar(CP_ACP
, 0, string
, -1, buffer
, MAX_STRING_LEN
);
1215 BOOL CALLBACK
datetime_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1221 WCHAR buffer
[MAX_STRING_LEN
];
1223 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
1226 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, 0, (LPWSTR
)&buffer
,
1228 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1229 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, 0, (LPWSTR
)&buffer
,
1231 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1232 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, 0, (LPWSTR
)&buffer
, MAX_STRING_LEN
);
1233 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1235 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1240 switch(LOWORD(wParam
))
1245 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
1247 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1251 WCHAR buffer
[MAX_STRING_LEN
];
1252 SendMessageW(hListWnd
, LB_GETTEXT
, index
, (LPARAM
)&buffer
);
1253 SendMessageW(hEditorWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)&buffer
);
1259 EndDialog(hWnd
, wParam
);
1266 BOOL CALLBACK
newfile_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1272 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
1273 WCHAR buffer
[MAX_STRING_LEN
];
1274 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1276 LoadStringW(hInstance
, STRING_NEWFILE_RICHTEXT
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
1277 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1278 LoadStringW(hInstance
, STRING_NEWFILE_TXT
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
1279 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1280 LoadStringW(hInstance
, STRING_NEWFILE_TXT_UNICODE
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
1281 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1283 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1288 switch(LOWORD(wParam
))
1293 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1294 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1297 EndDialog(hWnd
, MAKELONG(fileformat_flags(index
),0));
1302 EndDialog(hWnd
, MAKELONG(ID_NEWFILE_ABORT
,0));
1309 static INT_PTR CALLBACK
paraformat_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1315 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
,
1317 WCHAR buffer
[MAX_STRING_LEN
];
1318 HWND hListWnd
= GetDlgItem(hWnd
, IDC_PARA_ALIGN
);
1319 HWND hLeftWnd
= GetDlgItem(hWnd
, IDC_PARA_LEFT
);
1320 HWND hRightWnd
= GetDlgItem(hWnd
, IDC_PARA_RIGHT
);
1321 HWND hFirstWnd
= GetDlgItem(hWnd
, IDC_PARA_FIRST
);
1325 LoadStringW(hInstance
, STRING_ALIGN_LEFT
, buffer
,
1327 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1328 LoadStringW(hInstance
, STRING_ALIGN_RIGHT
, buffer
,
1330 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1331 LoadStringW(hInstance
, STRING_ALIGN_CENTER
, buffer
,
1333 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1335 pf
.cbSize
= sizeof(pf
);
1336 pf
.dwMask
= PFM_ALIGNMENT
| PFM_OFFSET
| PFM_RIGHTINDENT
|
1338 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1340 if(pf
.wAlignment
== PFA_RIGHT
)
1342 else if(pf
.wAlignment
== PFA_CENTER
)
1345 SendMessageW(hListWnd
, CB_SETCURSEL
, index
, 0);
1347 number_with_units(buffer
, pf
.dxOffset
);
1348 SetWindowTextW(hLeftWnd
, buffer
);
1349 number_with_units(buffer
, pf
.dxRightIndent
);
1350 SetWindowTextW(hRightWnd
, buffer
);
1351 number_with_units(buffer
, pf
.dxStartIndent
- pf
.dxOffset
);
1352 SetWindowTextW(hFirstWnd
, buffer
);
1357 switch(LOWORD(wParam
))
1361 HWND hLeftWnd
= GetDlgItem(hWnd
, IDC_PARA_LEFT
);
1362 HWND hRightWnd
= GetDlgItem(hWnd
, IDC_PARA_RIGHT
);
1363 HWND hFirstWnd
= GetDlgItem(hWnd
, IDC_PARA_FIRST
);
1364 WCHAR buffer
[MAX_STRING_LEN
];
1369 GetWindowTextW(hLeftWnd
, buffer
, MAX_STRING_LEN
);
1370 if(number_from_string(buffer
, &num
, TRUE
))
1372 pf
.dxOffset
= current_units_to_twips(num
);
1373 GetWindowTextW(hRightWnd
, buffer
, MAX_STRING_LEN
);
1374 if(number_from_string(buffer
, &num
, TRUE
))
1376 pf
.dxRightIndent
= current_units_to_twips(num
);
1377 GetWindowTextW(hFirstWnd
, buffer
, MAX_STRING_LEN
);
1378 if(number_from_string(buffer
, &num
, TRUE
))
1380 pf
.dxStartIndent
= current_units_to_twips(num
);
1384 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
1385 wszAppTitle
, MB_OK
| MB_ICONASTERISK
);
1389 pf
.dxStartIndent
= pf
.dxStartIndent
+ pf
.dxOffset
;
1390 pf
.cbSize
= sizeof(pf
);
1391 pf
.dwMask
= PFM_OFFSET
| PFM_OFFSETINDENT
| PFM_RIGHTINDENT
;
1392 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1398 EndDialog(hWnd
, wParam
);
1405 static INT_PTR CALLBACK
tabstops_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1411 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1413 WCHAR buffer
[MAX_STRING_LEN
];
1416 pf
.cbSize
= sizeof(pf
);
1417 pf
.dwMask
= PFM_TABSTOPS
;
1418 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1419 SendMessageW(hTabWnd
, CB_LIMITTEXT
, MAX_STRING_LEN
-1, 0);
1421 for(i
= 0; i
< pf
.cTabCount
; i
++)
1423 number_with_units(buffer
, pf
.rgxTabs
[i
]);
1424 SendMessageW(hTabWnd
, CB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1431 switch(LOWORD(wParam
))
1435 HWND hTabWnd
= (HWND
)lParam
;
1436 HWND hAddWnd
= GetDlgItem(hWnd
, ID_TAB_ADD
);
1437 HWND hDelWnd
= GetDlgItem(hWnd
, ID_TAB_DEL
);
1438 HWND hEmptyWnd
= GetDlgItem(hWnd
, ID_TAB_EMPTY
);
1440 if(GetWindowTextLengthW(hTabWnd
))
1441 EnableWindow(hAddWnd
, TRUE
);
1443 EnableWindow(hAddWnd
, FALSE
);
1445 if(SendMessageW(hTabWnd
, CB_GETCOUNT
, 0, 0))
1447 EnableWindow(hEmptyWnd
, TRUE
);
1449 if(SendMessageW(hTabWnd
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
1450 EnableWindow(hDelWnd
, FALSE
);
1452 EnableWindow(hDelWnd
, TRUE
);
1455 EnableWindow(hEmptyWnd
, FALSE
);
1462 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1463 WCHAR buffer
[MAX_STRING_LEN
];
1465 GetWindowTextW(hTabWnd
, buffer
, MAX_STRING_LEN
);
1466 append_current_units(buffer
);
1468 if(SendMessageW(hTabWnd
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)&buffer
) == CB_ERR
)
1472 if(!number_from_string(buffer
, &number
, TRUE
))
1474 MessageBoxW(hWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
1475 wszAppTitle
, MB_OK
| MB_ICONINFORMATION
);
1478 SendMessageW(hTabWnd
, CB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1479 SetWindowTextW(hTabWnd
, 0);
1488 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1490 ret
= SendMessageW(hTabWnd
, CB_GETCURSEL
, 0, 0);
1492 SendMessageW(hTabWnd
, CB_DELETESTRING
, ret
, 0);
1498 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1499 SendMessageW(hTabWnd
, CB_RESETCONTENT
, 0, 0);
1506 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1508 WCHAR buffer
[MAX_STRING_LEN
];
1512 pf
.cbSize
= sizeof(pf
);
1513 pf
.dwMask
= PFM_TABSTOPS
;
1515 for(i
= 0; SendMessageW(hTabWnd
, CB_GETLBTEXT
, i
,
1516 (LPARAM
)&buffer
) != CB_ERR
&&
1517 i
< MAX_TAB_STOPS
; i
++)
1519 number_from_string(buffer
, &number
, TRUE
);
1520 pf
.rgxTabs
[i
] = current_units_to_twips(number
);
1523 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1527 EndDialog(hWnd
, wParam
);
1534 static int context_menu(LPARAM lParam
)
1536 int x
= (int)(short)LOWORD(lParam
);
1537 int y
= (int)(short)HIWORD(lParam
);
1538 HMENU hPop
= GetSubMenu(hPopupMenu
, 0);
1542 int from
= 0, to
= 0;
1544 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
1545 SendMessageW(hEditorWnd
, EM_POSFROMCHAR
, (WPARAM
)&pt
, (LPARAM
)to
);
1546 ClientToScreen(hEditorWnd
, (POINT
*)&pt
);
1551 TrackPopupMenu(hPop
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
,
1552 x
, y
, 0, hMainWnd
, 0);
1557 static LRESULT
OnCreate( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1559 HWND hToolBarWnd
, hFormatBarWnd
, hReBarWnd
, hFontListWnd
, hSizeListWnd
, hRulerWnd
;
1560 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1563 int nStdBitmaps
= 0;
1566 static const WCHAR wszRichEditDll
[] = {'R','I','C','H','E','D','2','0','.','D','L','L','\0'};
1567 static const WCHAR wszRichEditText
[] = {'R','i','c','h','E','d','i','t',' ','t','e','x','t','\0'};
1569 CreateStatusWindowW(CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
, wszRichEditText
, hWnd
, IDC_STATUSBAR
);
1571 hReBarWnd
= CreateWindowExW(WS_EX_TOOLWINDOW
, REBARCLASSNAMEW
, NULL
,
1572 CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|RBS_VARHEIGHT
|CCS_TOP
,
1573 CW_USEDEFAULT
, CW_USEDEFAULT
, 0, 0, hWnd
, (HMENU
)IDC_REBAR
, hInstance
, NULL
);
1575 rbi
.cbSize
= sizeof(rbi
);
1578 if(!SendMessageW(hReBarWnd
, RB_SETBARINFO
, 0, (LPARAM
)&rbi
))
1581 hToolBarWnd
= CreateToolbarEx(hReBarWnd
, CCS_NOPARENTALIGN
|CCS_NOMOVEY
|WS_VISIBLE
|WS_CHILD
|TBSTYLE_TOOLTIPS
|TBSTYLE_BUTTON
,
1583 1, hInstance
, IDB_TOOLBAR
,
1585 24, 24, 16, 16, sizeof(TBBUTTON
));
1587 ab
.hInst
= HINST_COMMCTRL
;
1588 ab
.nID
= IDB_STD_SMALL_COLOR
;
1589 nStdBitmaps
= SendMessageW(hToolBarWnd
, TB_ADDBITMAP
, 0, (LPARAM
)&ab
);
1591 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILENEW
, ID_FILE_NEW
);
1592 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILEOPEN
, ID_FILE_OPEN
);
1593 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILESAVE
, ID_FILE_SAVE
);
1594 AddSeparator(hToolBarWnd
);
1595 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINT
, ID_PRINT_QUICK
);
1596 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINTPRE
, ID_PREVIEW
);
1597 AddSeparator(hToolBarWnd
);
1598 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FIND
, ID_FIND
);
1599 AddSeparator(hToolBarWnd
);
1600 AddButton(hToolBarWnd
, nStdBitmaps
+STD_CUT
, ID_EDIT_CUT
);
1601 AddButton(hToolBarWnd
, nStdBitmaps
+STD_COPY
, ID_EDIT_COPY
);
1602 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PASTE
, ID_EDIT_PASTE
);
1603 AddButton(hToolBarWnd
, nStdBitmaps
+STD_UNDO
, ID_EDIT_UNDO
);
1604 AddButton(hToolBarWnd
, nStdBitmaps
+STD_REDOW
, ID_EDIT_REDO
);
1605 AddSeparator(hToolBarWnd
);
1606 AddButton(hToolBarWnd
, 0, ID_DATETIME
);
1608 SendMessageW(hToolBarWnd
, TB_AUTOSIZE
, 0, 0);
1610 rbb
.cbSize
= sizeof(rbb
);
1611 rbb
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
| RBBIM_STYLE
| RBBIM_ID
;
1612 rbb
.fStyle
= RBBS_CHILDEDGE
| RBBS_BREAK
| RBBS_NOGRIPPER
;
1614 rbb
.hwndChild
= hToolBarWnd
;
1616 rbb
.cyChild
= rbb
.cyMinChild
= HIWORD(SendMessageW(hToolBarWnd
, TB_GETBUTTONSIZE
, 0, 0));
1617 rbb
.wID
= BANDID_TOOLBAR
;
1619 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1621 hFontListWnd
= CreateWindowExW(0, WC_COMBOBOXEXW
, NULL
,
1622 WS_BORDER
| WS_VISIBLE
| WS_CHILD
| CBS_DROPDOWN
| CBS_SORT
,
1623 0, 0, 200, 150, hReBarWnd
, (HMENU
)IDC_FONTLIST
, hInstance
, NULL
);
1625 rbb
.hwndChild
= hFontListWnd
;
1627 rbb
.wID
= BANDID_FONTLIST
;
1629 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1631 hSizeListWnd
= CreateWindowExW(0, WC_COMBOBOXEXW
, NULL
,
1632 WS_BORDER
| WS_VISIBLE
| WS_CHILD
| CBS_DROPDOWN
,
1633 0, 0, 50, 150, hReBarWnd
, (HMENU
)IDC_SIZELIST
, hInstance
, NULL
);
1635 rbb
.hwndChild
= hSizeListWnd
;
1637 rbb
.fStyle
^= RBBS_BREAK
;
1638 rbb
.wID
= BANDID_SIZELIST
;
1640 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1642 hFormatBarWnd
= CreateToolbarEx(hReBarWnd
,
1643 CCS_NOPARENTALIGN
| CCS_NOMOVEY
| WS_VISIBLE
| TBSTYLE_TOOLTIPS
| TBSTYLE_BUTTON
,
1644 IDC_FORMATBAR
, 7, hInstance
, IDB_FORMATBAR
, NULL
, 0, 16, 16, 16, 16, sizeof(TBBUTTON
));
1646 AddButton(hFormatBarWnd
, 0, ID_FORMAT_BOLD
);
1647 AddButton(hFormatBarWnd
, 1, ID_FORMAT_ITALIC
);
1648 AddButton(hFormatBarWnd
, 2, ID_FORMAT_UNDERLINE
);
1649 AddSeparator(hFormatBarWnd
);
1650 AddButton(hFormatBarWnd
, 3, ID_ALIGN_LEFT
);
1651 AddButton(hFormatBarWnd
, 4, ID_ALIGN_CENTER
);
1652 AddButton(hFormatBarWnd
, 5, ID_ALIGN_RIGHT
);
1653 AddSeparator(hFormatBarWnd
);
1654 AddButton(hFormatBarWnd
, 6, ID_BULLET
);
1656 SendMessageW(hFormatBarWnd
, TB_AUTOSIZE
, 0, 0);
1658 rbb
.hwndChild
= hFormatBarWnd
;
1659 rbb
.wID
= BANDID_FORMATBAR
;
1661 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1663 hRulerWnd
= CreateWindowExW(0, WC_STATICW
, NULL
, WS_VISIBLE
| WS_CHILD
,
1664 0, 0, 200, 10, hReBarWnd
, (HMENU
)IDC_RULER
, hInstance
, NULL
);
1667 rbb
.hwndChild
= hRulerWnd
;
1668 rbb
.wID
= BANDID_RULER
;
1669 rbb
.fStyle
|= RBBS_BREAK
;
1671 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1673 hDLL
= LoadLibraryW(wszRichEditDll
);
1676 MessageBoxW(hWnd
, MAKEINTRESOURCEW(STRING_LOAD_RICHED_FAILED
), wszAppTitle
,
1677 MB_OK
| MB_ICONEXCLAMATION
);
1681 hEditorWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, wszRichEditClass
, NULL
,
1682 WS_CHILD
|WS_VISIBLE
|ECO_SELECTIONBAR
|ES_MULTILINE
|ES_AUTOVSCROLL
|ES_WANTRETURN
|WS_VSCROLL
,
1683 0, 0, 1000, 100, hWnd
, (HMENU
)IDC_EDITOR
, hInstance
, NULL
);
1687 fprintf(stderr
, "Error code %u\n", GetLastError());
1692 SetFocus(hEditorWnd
);
1693 SendMessageW(hEditorWnd
, EM_SETEVENTMASK
, 0, ENM_SELCHANGE
);
1697 populate_font_list(hFontListWnd
);
1698 populate_size_list(hSizeListWnd
);
1700 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
1702 ID_FINDMSGSTRING
= RegisterWindowMessageW(FINDMSGSTRINGW
);
1704 registry_read_filelist(hWnd
);
1705 registry_read_formatopts_all(barState
, wordWrap
);
1706 registry_read_options();
1707 DragAcceptFiles(hWnd
, TRUE
);
1712 static LRESULT
OnUser( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1714 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1715 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
1716 HWND hwndToolBar
= GetDlgItem(hwndReBar
, IDC_TOOLBAR
);
1717 HWND hwndFormatBar
= GetDlgItem(hwndReBar
, IDC_FORMATBAR
);
1723 ZeroMemory(&fmt
, sizeof(fmt
));
1724 fmt
.cbSize
= sizeof(fmt
);
1726 ZeroMemory(&pf
, sizeof(pf
));
1727 pf
.cbSize
= sizeof(pf
);
1729 gt
.flags
= GTL_NUMCHARS
;
1732 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_FIND
,
1733 SendMessageW(hwndEditor
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0) ? 1 : 0);
1735 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, TRUE
, (LPARAM
)&fmt
);
1737 SendMessageW(hwndEditor
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
1738 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_UNDO
,
1739 SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0));
1740 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_REDO
,
1741 SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0));
1742 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_CUT
, from
== to
? 0 : 1);
1743 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_COPY
, from
== to
? 0 : 1);
1745 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_BOLD
, (fmt
.dwMask
& CFM_BOLD
) &&
1746 (fmt
.dwEffects
& CFE_BOLD
));
1747 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_BOLD
, !(fmt
.dwMask
& CFM_BOLD
));
1748 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_ITALIC
, (fmt
.dwMask
& CFM_ITALIC
) &&
1749 (fmt
.dwEffects
& CFE_ITALIC
));
1750 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_ITALIC
, !(fmt
.dwMask
& CFM_ITALIC
));
1751 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_UNDERLINE
, (fmt
.dwMask
& CFM_UNDERLINE
) &&
1752 (fmt
.dwEffects
& CFE_UNDERLINE
));
1753 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_UNDERLINE
, !(fmt
.dwMask
& CFM_UNDERLINE
));
1755 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1756 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_LEFT
, (pf
.wAlignment
== PFA_LEFT
));
1757 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_CENTER
, (pf
.wAlignment
== PFA_CENTER
));
1758 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_RIGHT
, (pf
.wAlignment
== PFA_RIGHT
));
1760 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_BULLET
, (pf
.wNumbering
& PFN_BULLET
));
1764 static LRESULT
OnNotify( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1766 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1767 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
1768 NMHDR
*pHdr
= (NMHDR
*)lParam
;
1769 HWND hwndFontList
= GetDlgItem(hwndReBar
, IDC_FONTLIST
);
1770 HWND hwndSizeList
= GetDlgItem(hwndReBar
, IDC_SIZELIST
);
1771 WCHAR sizeBuffer
[MAX_PATH
];
1773 if (pHdr
->hwndFrom
== hwndFontList
|| pHdr
->hwndFrom
== hwndSizeList
)
1775 if (pHdr
->code
== CBEN_ENDEDITW
)
1777 CHARFORMAT2W format
;
1778 NMCBEENDEDIT
*endEdit
= (NMCBEENDEDIT
*)lParam
;
1780 ZeroMemory(&format
, sizeof(format
));
1781 format
.cbSize
= sizeof(format
);
1782 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&format
);
1784 if(pHdr
->hwndFrom
== hwndFontList
)
1786 if(lstrcmpW(format
.szFaceName
, (LPWSTR
)endEdit
->szText
))
1787 set_font((LPCWSTR
) endEdit
->szText
);
1788 } else if (pHdr
->hwndFrom
== hwndSizeList
)
1790 wsprintfW(sizeBuffer
, stringFormat
, format
.yHeight
/ 20);
1791 if(lstrcmpW(sizeBuffer
, (LPWSTR
)endEdit
->szText
))
1794 if(number_from_string((LPWSTR
)endEdit
->szText
, &size
, FALSE
))
1799 SetWindowTextW(hwndSizeList
, sizeBuffer
);
1800 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
), wszAppTitle
, MB_OK
| MB_ICONINFORMATION
);
1808 if (pHdr
->hwndFrom
!= hwndEditor
)
1811 if (pHdr
->code
== EN_SELCHANGE
)
1813 SELCHANGE
*pSC
= (SELCHANGE
*)lParam
;
1818 sprintf( buf
,"selection = %d..%d, line count=%ld",
1819 pSC
->chrg
.cpMin
, pSC
->chrg
.cpMax
,
1820 SendMessage(hwndEditor
, EM_GETLINECOUNT
, 0, 0));
1821 SetWindowText(GetDlgItem(hWnd
, IDC_STATUSBAR
), buf
);
1822 SendMessage(hWnd
, WM_USER
, 0, 0);
1828 static LRESULT
OnCommand( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1830 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1831 static FINDREPLACEW findreplace
;
1833 if ((HWND
)lParam
== hwndEditor
)
1836 switch(LOWORD(wParam
))
1840 PostMessageW(hWnd
, WM_CLOSE
, 0, 0);
1845 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1846 int ret
= DialogBox(hInstance
, MAKEINTRESOURCE(IDD_NEWFILE
), hWnd
,
1847 (DLGPROC
)newfile_proc
);
1849 if(ret
!= ID_NEWFILE_ABORT
)
1851 if(prompt_save_changes())
1856 wszFileName
[0] = '\0';
1860 st
.flags
= ST_DEFAULT
;
1862 SendMessageW(hEditorWnd
, EM_SETTEXTEX
, (WPARAM
)&st
, 0);
1864 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
1865 set_fileformat(ret
);
1879 DoSaveFile(wszFileName
, fileFormat
);
1884 case ID_FILE_SAVEAS
:
1888 case ID_FILE_RECENT1
:
1889 case ID_FILE_RECENT2
:
1890 case ID_FILE_RECENT3
:
1891 case ID_FILE_RECENT4
:
1893 HMENU hMenu
= GetMenu(hWnd
);
1896 mi
.cbSize
= sizeof(MENUITEMINFOW
);
1897 mi
.fMask
= MIIM_DATA
;
1898 if(GetMenuItemInfoW(hMenu
, LOWORD(wParam
), FALSE
, &mi
))
1899 DoOpenFile((LPWSTR
)mi
.dwItemData
);
1904 dialog_find(&findreplace
, FALSE
);
1908 handle_findmsg(&findreplace
);
1912 dialog_find(&findreplace
, TRUE
);
1915 case ID_FONTSETTINGS
:
1916 dialog_choose_font();
1920 dialog_print(hWnd
, wszFileName
);
1921 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
1924 case ID_PRINT_QUICK
:
1925 print_quick(wszFileName
);
1926 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
1931 int index
= reg_formatindex(fileFormat
);
1932 DWORD tmp
= barState
[index
];
1933 barState
[index
] = 0;
1935 barState
[index
] = tmp
;
1936 ShowWindow(hEditorWnd
, FALSE
);
1938 init_preview(hWnd
, wszFileName
);
1940 SetMenu(hWnd
, NULL
);
1941 InvalidateRect(0, 0, TRUE
);
1946 dialog_printsetup(hWnd
);
1947 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
1950 case ID_FORMAT_BOLD
:
1951 case ID_FORMAT_ITALIC
:
1952 case ID_FORMAT_UNDERLINE
:
1955 int effects
= CFE_BOLD
;
1957 ZeroMemory(&fmt
, sizeof(fmt
));
1958 fmt
.cbSize
= sizeof(fmt
);
1959 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
1961 fmt
.dwMask
= CFM_BOLD
;
1963 if (LOWORD(wParam
) == ID_FORMAT_ITALIC
)
1965 effects
= CFE_ITALIC
;
1966 fmt
.dwMask
= CFM_ITALIC
;
1967 } else if (LOWORD(wParam
) == ID_FORMAT_UNDERLINE
)
1969 effects
= CFE_UNDERLINE
;
1970 fmt
.dwMask
= CFM_UNDERLINE
;
1973 fmt
.dwEffects
^= effects
;
1975 SendMessageW(hwndEditor
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
1980 PostMessageW(hwndEditor
, WM_CUT
, 0, 0);
1984 PostMessageW(hwndEditor
, WM_COPY
, 0, 0);
1988 PostMessageW(hwndEditor
, WM_PASTE
, 0, 0);
1992 PostMessageW(hwndEditor
, WM_CLEAR
, 0, 0);
1995 case ID_EDIT_SELECTALL
:
1997 CHARRANGE range
= {0, -1};
1998 SendMessageW(hwndEditor
, EM_EXSETSEL
, 0, (LPARAM
)&range
);
1999 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2003 case ID_EDIT_GETTEXT
:
2005 int nLen
= GetWindowTextLengthW(hwndEditor
);
2006 LPWSTR data
= HeapAlloc( GetProcessHeap(), 0, (nLen
+1)*sizeof(WCHAR
) );
2009 GetWindowTextW(hwndEditor
, data
, nLen
+1);
2010 MessageBoxW(NULL
, data
, xszAppTitle
, MB_OK
);
2012 HeapFree( GetProcessHeap(), 0, data
);
2013 data
= HeapAlloc(GetProcessHeap(), 0, (nLen
+1)*sizeof(WCHAR
));
2015 tr
.chrg
.cpMax
= nLen
;
2016 tr
.lpstrText
= data
;
2017 SendMessage (hwndEditor
, EM_GETTEXTRANGE
, 0, (LPARAM
)&tr
);
2018 MessageBoxW(NULL
, data
, xszAppTitle
, MB_OK
);
2019 HeapFree( GetProcessHeap(), 0, data
);
2021 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2025 case ID_EDIT_CHARFORMAT
:
2026 case ID_EDIT_DEFCHARFORMAT
:
2030 ZeroMemory(&cf
, sizeof(cf
));
2031 cf
.cbSize
= sizeof(cf
);
2033 i
= SendMessageW(hwndEditor
, EM_GETCHARFORMAT
,
2034 LOWORD(wParam
) == ID_EDIT_CHARFORMAT
, (LPARAM
)&cf
);
2038 case ID_EDIT_PARAFORMAT
:
2041 ZeroMemory(&pf
, sizeof(pf
));
2042 pf
.cbSize
= sizeof(pf
);
2043 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2047 case ID_EDIT_SELECTIONINFO
:
2049 CHARRANGE range
= {0, -1};
2053 SendMessage(hwndEditor
, EM_EXGETSEL
, 0, (LPARAM
)&range
);
2054 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
) * (range
.cpMax
-range
.cpMin
+1));
2055 SendMessage(hwndEditor
, EM_GETSELTEXT
, 0, (LPARAM
)data
);
2056 sprintf(buf
, "Start = %d, End = %d", range
.cpMin
, range
.cpMax
);
2057 MessageBoxA(hWnd
, buf
, "Editor", MB_OK
);
2058 MessageBoxW(hWnd
, data
, xszAppTitle
, MB_OK
);
2059 HeapFree( GetProcessHeap(), 0, data
);
2060 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2064 case ID_EDIT_READONLY
:
2066 long nStyle
= GetWindowLong(hwndEditor
, GWL_STYLE
);
2067 if (nStyle
& ES_READONLY
)
2068 SendMessageW(hwndEditor
, EM_SETREADONLY
, 0, 0);
2070 SendMessageW(hwndEditor
, EM_SETREADONLY
, 1, 0);
2074 case ID_EDIT_MODIFIED
:
2075 if (SendMessageW(hwndEditor
, EM_GETMODIFY
, 0, 0))
2076 SendMessageW(hwndEditor
, EM_SETMODIFY
, 0, 0);
2078 SendMessageW(hwndEditor
, EM_SETMODIFY
, 1, 0);
2082 SendMessageW(hwndEditor
, EM_UNDO
, 0, 0);
2086 SendMessageW(hwndEditor
, EM_REDO
, 0, 0);
2093 pf
.cbSize
= sizeof(pf
);
2094 pf
.dwMask
= PFM_NUMBERING
;
2095 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2097 pf
.dwMask
|= PFM_OFFSET
;
2099 if(pf
.wNumbering
== PFN_BULLET
)
2105 pf
.wNumbering
= PFN_BULLET
;
2109 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
2114 case ID_ALIGN_CENTER
:
2115 case ID_ALIGN_RIGHT
:
2119 pf
.cbSize
= sizeof(pf
);
2120 pf
.dwMask
= PFM_ALIGNMENT
;
2121 switch(LOWORD(wParam
)) {
2122 case ID_ALIGN_LEFT
: pf
.wAlignment
= PFA_LEFT
; break;
2123 case ID_ALIGN_CENTER
: pf
.wAlignment
= PFA_CENTER
; break;
2124 case ID_ALIGN_RIGHT
: pf
.wAlignment
= PFA_RIGHT
; break;
2126 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
2131 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 1, 0);
2135 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 0, RGB(255,255,192));
2138 case ID_TOGGLE_TOOLBAR
:
2139 set_toolbar_state(BANDID_TOOLBAR
, !is_bar_visible(BANDID_TOOLBAR
));
2143 case ID_TOGGLE_FORMATBAR
:
2144 set_toolbar_state(BANDID_FONTLIST
, !is_bar_visible(BANDID_FORMATBAR
));
2145 set_toolbar_state(BANDID_SIZELIST
, !is_bar_visible(BANDID_FORMATBAR
));
2146 set_toolbar_state(BANDID_FORMATBAR
, !is_bar_visible(BANDID_FORMATBAR
));
2150 case ID_TOGGLE_STATUSBAR
:
2151 set_statusbar_state(!is_bar_visible(BANDID_STATUSBAR
));
2155 case ID_TOGGLE_RULER
:
2156 set_toolbar_state(BANDID_RULER
, !is_bar_visible(BANDID_RULER
));
2162 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
2163 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_DATETIME
), hWnd
, (DLGPROC
)datetime_proc
);
2169 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
2170 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_PARAFORMAT
), hWnd
,
2177 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
2178 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_TABSTOPS
), hWnd
, tabstops_proc
);
2186 case ID_VIEWPROPERTIES
:
2187 dialog_viewproperties();
2191 SendMessageW(hwndEditor
, WM_COMMAND
, wParam
, lParam
);
2197 static LRESULT
OnInitPopupMenu( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
2199 HMENU hMenu
= (HMENU
)wParam
;
2200 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2201 HWND hwndStatus
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
2203 int nAlignment
= -1;
2209 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&selFrom
, (LPARAM
)&selTo
);
2210 EnableMenuItem(hMenu
, ID_EDIT_COPY
, MF_BYCOMMAND
|(selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
2211 EnableMenuItem(hMenu
, ID_EDIT_CUT
, MF_BYCOMMAND
|(selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
2213 pf
.cbSize
= sizeof(PARAFORMAT
);
2214 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2215 CheckMenuItem(hMenu
, ID_EDIT_READONLY
,
2216 MF_BYCOMMAND
|(GetWindowLong(hwndEditor
, GWL_STYLE
)&ES_READONLY
? MF_CHECKED
: MF_UNCHECKED
));
2217 CheckMenuItem(hMenu
, ID_EDIT_MODIFIED
,
2218 MF_BYCOMMAND
|(SendMessage(hwndEditor
, EM_GETMODIFY
, 0, 0) ? MF_CHECKED
: MF_UNCHECKED
));
2219 if (pf
.dwMask
& PFM_ALIGNMENT
)
2220 nAlignment
= pf
.wAlignment
;
2221 CheckMenuItem(hMenu
, ID_ALIGN_LEFT
, MF_BYCOMMAND
|(nAlignment
== PFA_LEFT
) ?
2222 MF_CHECKED
: MF_UNCHECKED
);
2223 CheckMenuItem(hMenu
, ID_ALIGN_CENTER
, MF_BYCOMMAND
|(nAlignment
== PFA_CENTER
) ?
2224 MF_CHECKED
: MF_UNCHECKED
);
2225 CheckMenuItem(hMenu
, ID_ALIGN_RIGHT
, MF_BYCOMMAND
|(nAlignment
== PFA_RIGHT
) ?
2226 MF_CHECKED
: MF_UNCHECKED
);
2227 CheckMenuItem(hMenu
, ID_BULLET
, MF_BYCOMMAND
| ((pf
.wNumbering
== PFN_BULLET
) ?
2228 MF_CHECKED
: MF_UNCHECKED
));
2229 EnableMenuItem(hMenu
, ID_EDIT_UNDO
, MF_BYCOMMAND
|(SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0)) ?
2230 MF_ENABLED
: MF_GRAYED
);
2231 EnableMenuItem(hMenu
, ID_EDIT_REDO
, MF_BYCOMMAND
|(SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0)) ?
2232 MF_ENABLED
: MF_GRAYED
);
2234 CheckMenuItem(hMenu
, ID_TOGGLE_TOOLBAR
, MF_BYCOMMAND
|(is_bar_visible(BANDID_TOOLBAR
)) ?
2235 MF_CHECKED
: MF_UNCHECKED
);
2237 CheckMenuItem(hMenu
, ID_TOGGLE_FORMATBAR
, MF_BYCOMMAND
|(is_bar_visible(BANDID_FORMATBAR
)) ?
2238 MF_CHECKED
: MF_UNCHECKED
);
2240 CheckMenuItem(hMenu
, ID_TOGGLE_STATUSBAR
, MF_BYCOMMAND
|IsWindowVisible(hwndStatus
) ?
2241 MF_CHECKED
: MF_UNCHECKED
);
2243 CheckMenuItem(hMenu
, ID_TOGGLE_RULER
, MF_BYCOMMAND
|(is_bar_visible(BANDID_RULER
)) ? MF_CHECKED
: MF_UNCHECKED
);
2245 gt
.flags
= GTL_NUMCHARS
;
2247 textLength
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
2248 EnableMenuItem(hMenu
, ID_FIND
, MF_BYCOMMAND
|(textLength
? MF_ENABLED
: MF_GRAYED
));
2250 mi
.cbSize
= sizeof(mi
);
2251 mi
.fMask
= MIIM_DATA
;
2253 GetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
2255 EnableMenuItem(hMenu
, ID_FIND_NEXT
, MF_BYCOMMAND
|((textLength
&& mi
.dwItemData
) ?
2256 MF_ENABLED
: MF_GRAYED
));
2258 EnableMenuItem(hMenu
, ID_REPLACE
, MF_BYCOMMAND
|(textLength
? MF_ENABLED
: MF_GRAYED
));
2263 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
2265 int nStatusSize
= 0;
2267 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2268 HWND hwndStatusBar
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
2269 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
2270 HWND hRulerWnd
= GetDlgItem(hWnd
, IDC_RULER
);
2271 int rebarHeight
= 0;
2276 SendMessageW(hwndStatusBar
, WM_SIZE
, 0, 0);
2277 if (IsWindowVisible(hwndStatusBar
))
2279 GetClientRect(hwndStatusBar
, &rc
);
2280 nStatusSize
= rc
.bottom
- rc
.top
;
2288 if(!is_bar_visible(BANDID_TOOLBAR
))
2291 if(!is_bar_visible(BANDID_FORMATBAR
))
2294 rebarHeight
= rebarRows
? SendMessageW(hwndReBar
, RB_GETBARHEIGHT
, 0, 0) : 0;
2296 MoveWindow(hwndReBar
, 0, 0, LOWORD(lParam
), rebarHeight
, TRUE
);
2300 GetClientRect(hWnd
, &rc
);
2301 MoveWindow(hwndEditor
, 0, rebarHeight
, rc
.right
, rc
.bottom
-nStatusSize
-rebarHeight
, TRUE
);
2304 redraw_ruler(hRulerWnd
);
2306 return DefWindowProcW(hWnd
, WM_SIZE
, wParam
, lParam
);
2309 static LRESULT CALLBACK
WndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2311 if(msg
== ID_FINDMSGSTRING
)
2312 return handle_findmsg((LPFINDREPLACEW
)lParam
);
2317 return OnCreate( hWnd
, wParam
, lParam
);
2320 return OnUser( hWnd
, wParam
, lParam
);
2323 return OnNotify( hWnd
, wParam
, lParam
);
2326 if(preview_isactive())
2328 return preview_command( hWnd
, wParam
, lParam
);
2331 return OnCommand( hWnd
, wParam
, lParam
);
2338 if(preview_isactive())
2341 } else if(prompt_save_changes())
2343 registry_set_options(hMainWnd
);
2344 registry_set_formatopts_all(barState
);
2351 SetFocus(GetDlgItem(hWnd
, IDC_EDITOR
));
2354 case WM_INITMENUPOPUP
:
2355 return OnInitPopupMenu( hWnd
, wParam
, lParam
);
2358 return OnSize( hWnd
, wParam
, lParam
);
2360 case WM_CONTEXTMENU
:
2361 if((HWND
)wParam
== hEditorWnd
)
2362 return context_menu(lParam
);
2364 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2368 WCHAR file
[MAX_PATH
];
2369 DragQueryFileW((HDROP
)wParam
, 0, file
, MAX_PATH
);
2370 DragFinish((HDROP
)wParam
);
2372 if(prompt_save_changes())
2377 if(preview_isactive())
2378 return print_preview(hWnd
);
2380 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2383 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2389 int CALLBACK
WinMain(HINSTANCE hInstance
, HINSTANCE hOldInstance
, LPSTR szCmdParagraph
, int res
)
2391 INITCOMMONCONTROLSEX classes
= {8, ICC_BAR_CLASSES
|ICC_COOL_CLASSES
|ICC_USEREX_CLASSES
};
2396 UINT_PTR hPrevRulerProc
;
2399 static const WCHAR wszAccelTable
[] = {'M','A','I','N','A','C','C','E','L',
2400 'T','A','B','L','E','\0'};
2402 InitCommonControlsEx(&classes
);
2404 hAccel
= LoadAcceleratorsW(hInstance
, wszAccelTable
);
2406 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2407 wc
.lpfnWndProc
= WndProc
;
2410 wc
.hInstance
= hInstance
;
2411 wc
.hIcon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_WORDPAD
));
2412 wc
.hCursor
= LoadCursor(NULL
, IDC_IBEAM
);
2413 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
2414 wc
.lpszMenuName
= MAKEINTRESOURCEW(IDM_MAINMENU
);
2415 wc
.lpszClassName
= wszMainWndClass
;
2416 RegisterClassW(&wc
);
2418 registry_read_winrect(&rc
);
2419 hMainWnd
= CreateWindowExW(0, wszMainWndClass
, wszAppTitle
, WS_CLIPCHILDREN
|WS_OVERLAPPEDWINDOW
,
2420 rc
.left
, rc
.top
, rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, NULL
, NULL
, hInstance
, NULL
);
2421 ShowWindow(hMainWnd
, SW_SHOWDEFAULT
);
2425 set_fileformat(SF_RTF
);
2426 hPopupMenu
= LoadMenuW(hInstance
, MAKEINTRESOURCEW(IDM_POPUP
));
2427 get_default_printer_opts();
2428 target_device(hMainWnd
, wordWrap
[reg_formatindex(fileFormat
)]);
2430 hRulerWnd
= GetDlgItem(GetDlgItem(hMainWnd
, IDC_REBAR
), IDC_RULER
);
2431 SendMessageW(GetDlgItem(hMainWnd
, IDC_EDITOR
), EM_POSFROMCHAR
, (WPARAM
)&EditPoint
, 0);
2432 hPrevRulerProc
= SetWindowLongPtrW(hRulerWnd
, GWLP_WNDPROC
, (UINT_PTR
)ruler_proc
);
2433 SendMessageW(hRulerWnd
, WM_USER
, (WPARAM
)&EditPoint
, hPrevRulerProc
);
2435 HandleCommandLine(GetCommandLineW());
2437 while(GetMessageW(&msg
,0,0,0))
2439 if (IsDialogMessage(hFindWnd
, &msg
))
2442 if (TranslateAcceleratorW(hMainWnd
, hAccel
, &msg
))
2444 TranslateMessage(&msg
);
2445 DispatchMessageW(&msg
);
2446 if (!PeekMessageW(&msg
, 0, 0, 0, PM_NOREMOVE
))
2447 SendMessageW(hMainWnd
, WM_USER
, 0, 0);