2 * Wordpad implementation
4 * Copyright 2004 by Krzysztof Foltman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_LEAN_AND_MEAN
22 #define _WIN32_IE 0x0400
24 #define MAX_STRING_LEN 255
43 static const WCHAR xszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
44 static const WCHAR xszMainMenu
[] = {'M','A','I','N','M','E','N','U',0};
46 static const WCHAR wszRichEditClass
[] = {'R','I','C','H','E','D','I','T','2','0','W',0};
47 static const WCHAR wszMainWndClass
[] = {'W','O','R','D','P','A','D','T','O','P',0};
48 static const WCHAR wszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
50 static const WCHAR key_recentfiles
[] = {'R','e','c','e','n','t',' ','f','i','l','e',
51 ' ','l','i','s','t',0};
52 static const WCHAR key_options
[] = {'O','p','t','i','o','n','s',0};
53 static const WCHAR key_rtf
[] = {'R','T','F',0};
54 static const WCHAR key_text
[] = {'T','e','x','t',0};
56 static const WCHAR var_file
[] = {'F','i','l','e','%','d',0};
57 static const WCHAR var_framerect
[] = {'F','r','a','m','e','R','e','c','t',0};
58 static const WCHAR var_barstate0
[] = {'B','a','r','S','t','a','t','e','0',0};
59 static const WCHAR var_pagemargin
[] = {'P','a','g','e','M','a','r','g','i','n',0};
62 static HWND hEditorWnd
;
65 static UINT ID_FINDMSGSTRING
;
67 static WCHAR wszFilter
[MAX_STRING_LEN
*4+6*3+5];
68 static WCHAR wszDefaultFileName
[MAX_STRING_LEN
];
69 static WCHAR wszSaveChanges
[MAX_STRING_LEN
];
70 static WCHAR wszPrintFilter
[MAX_STRING_LEN
*2+6+4+1];
71 static WCHAR units_cmW
[MAX_STRING_LEN
];
73 static char units_cmA
[MAX_STRING_LEN
];
75 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
77 /* Load string resources */
78 static void DoLoadStrings(void)
81 static const WCHAR files_rtf
[] = {'*','.','r','t','f','\0'};
82 static const WCHAR files_txt
[] = {'*','.','t','x','t','\0'};
83 static const WCHAR files_all
[] = {'*','.','*','\0'};
84 static const WCHAR files_prn
[] = {'*','.','P','R','N',0};
85 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
87 LoadStringW(hInstance
, STRING_RICHTEXT_FILES_RTF
, p
, MAX_STRING_LEN
);
89 lstrcpyW(p
, files_rtf
);
91 LoadStringW(hInstance
, STRING_TEXT_FILES_TXT
, p
, MAX_STRING_LEN
);
93 lstrcpyW(p
, files_txt
);
95 LoadStringW(hInstance
, STRING_TEXT_FILES_UNICODE_TXT
, p
, MAX_STRING_LEN
);
97 lstrcpyW(p
, files_txt
);
99 LoadStringW(hInstance
, STRING_ALL_FILES
, p
, MAX_STRING_LEN
);
100 p
+= lstrlenW(p
) + 1;
101 lstrcpyW(p
, files_all
);
102 p
+= lstrlenW(p
) + 1;
106 LoadStringW(hInstance
, STRING_PRINTER_FILES_PRN
, p
, MAX_STRING_LEN
);
107 p
+= lstrlenW(p
) + 1;
108 lstrcpyW(p
, files_prn
);
109 p
+= lstrlenW(p
) + 1;
110 LoadStringW(hInstance
, STRING_ALL_FILES
, p
, MAX_STRING_LEN
);
111 p
+= lstrlenW(p
) + 1;
112 lstrcpyW(p
, files_all
);
113 p
+= lstrlenW(p
) + 1;
116 p
= wszDefaultFileName
;
117 LoadStringW(hInstance
, STRING_DEFAULT_FILENAME
, p
, MAX_STRING_LEN
);
120 LoadStringW(hInstance
, STRING_PROMPT_SAVE_CHANGES
, p
, MAX_STRING_LEN
);
122 LoadStringA(hInstance
, STRING_UNITS_CM
, units_cmA
, MAX_STRING_LEN
);
123 LoadStringW(hInstance
, STRING_UNITS_CM
, units_cmW
, MAX_STRING_LEN
);
126 static void AddButton(HWND hwndToolBar
, int nImage
, int nCommand
)
130 ZeroMemory(&button
, sizeof(button
));
131 button
.iBitmap
= nImage
;
132 button
.idCommand
= nCommand
;
133 button
.fsState
= TBSTATE_ENABLED
;
134 button
.fsStyle
= TBSTYLE_BUTTON
;
137 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
140 static void AddSeparator(HWND hwndToolBar
)
144 ZeroMemory(&button
, sizeof(button
));
146 button
.idCommand
= 0;
148 button
.fsStyle
= TBSTYLE_SEP
;
151 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
154 static DWORD CALLBACK
stream_in(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
156 HANDLE hFile
= (HANDLE
)cookie
;
159 if(!ReadFile(hFile
, buffer
, cb
, &read
, 0))
167 static DWORD CALLBACK
stream_out(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
171 HANDLE hFile
= (HANDLE
)cookie
;
173 ret
= WriteFile(hFile
, buffer
, cb
, &written
, 0);
175 if(!ret
|| (cb
!= written
))
184 static LPWSTR
file_basename(LPWSTR path
)
186 LPWSTR pos
= path
+ lstrlenW(path
);
190 if(*pos
== '\\' || *pos
== '/')
200 static WCHAR wszFileName
[MAX_PATH
];
201 static WPARAM fileFormat
= SF_RTF
;
203 static void set_caption(LPCWSTR wszNewFileName
)
205 static const WCHAR wszSeparator
[] = {' ','-',' '};
210 wszNewFileName
= wszDefaultFileName
;
212 wszNewFileName
= file_basename((LPWSTR
)wszNewFileName
);
214 wszCaption
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
215 lstrlenW(wszNewFileName
)*sizeof(WCHAR
)+sizeof(wszSeparator
)+sizeof(wszAppTitle
));
220 memcpy(wszCaption
, wszNewFileName
, lstrlenW(wszNewFileName
)*sizeof(WCHAR
));
221 length
+= lstrlenW(wszNewFileName
);
222 memcpy(wszCaption
+ length
, wszSeparator
, sizeof(wszSeparator
));
223 length
+= sizeof(wszSeparator
) / sizeof(WCHAR
);
224 memcpy(wszCaption
+ length
, wszAppTitle
, sizeof(wszAppTitle
));
226 SetWindowTextW(hMainWnd
, wszCaption
);
228 HeapFree(GetProcessHeap(), 0, wszCaption
);
231 static LRESULT
registry_get_handle(HKEY
*hKey
, LPDWORD action
, LPCWSTR subKey
)
234 static const WCHAR wszProgramKey
[] = {'S','o','f','t','w','a','r','e','\\',
235 'M','i','c','r','o','s','o','f','t','\\',
236 'W','i','n','d','o','w','s','\\',
237 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
238 'A','p','p','l','e','t','s','\\',
239 'W','o','r','d','p','a','d',0};
240 LPWSTR key
= (LPWSTR
)wszProgramKey
;
244 WCHAR backslash
[] = {'\\',0};
245 key
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
246 (lstrlenW(wszProgramKey
)+lstrlenW(subKey
)+lstrlenW(backslash
)+1)
252 lstrcpyW(key
, wszProgramKey
);
253 lstrcatW(key
, backslash
);
254 lstrcatW(key
, subKey
);
259 ret
= RegCreateKeyExW(HKEY_CURRENT_USER
, key
, 0, NULL
, REG_OPTION_NON_VOLATILE
,
260 KEY_READ
| KEY_WRITE
, NULL
, hKey
, action
);
263 ret
= RegOpenKeyExW(HKEY_CURRENT_USER
, key
, 0, KEY_READ
| KEY_WRITE
, hKey
);
267 HeapFree(GetProcessHeap(), 0, key
);
274 static void registry_set_options(void)
279 if(registry_get_handle(&hKey
, &action
, (LPWSTR
)key_options
) == ERROR_SUCCESS
)
283 GetWindowRect(hMainWnd
, &rc
);
285 RegSetValueExW(hKey
, var_framerect
, 0, REG_BINARY
, (LPBYTE
)&rc
, sizeof(RECT
));
287 RegSetValueExW(hKey
, var_pagemargin
, 0, REG_BINARY
, (LPBYTE
)&margins
, sizeof(RECT
));
291 static RECT
registry_read_winrect(void)
295 DWORD size
= sizeof(RECT
);
297 ZeroMemory(&rc
, sizeof(RECT
));
298 if(registry_get_handle(&hKey
, 0, (LPWSTR
)key_options
) != ERROR_SUCCESS
||
299 RegQueryValueExW(hKey
, var_framerect
, 0, NULL
, (LPBYTE
)&rc
, &size
) !=
300 ERROR_SUCCESS
|| size
!= sizeof(RECT
))
312 static void truncate_path(LPWSTR file
, LPWSTR out
, LPWSTR pos1
, LPWSTR pos2
)
314 static const WCHAR dots
[] = {'.','.','.',0};
323 static void format_filelist_filename(LPWSTR file
, LPWSTR out
)
326 LPWSTR truncpos1
, truncpos2
;
327 WCHAR myDocs
[MAX_STRING_LEN
];
329 SHGetFolderPathW(NULL
, CSIDL_PERSONAL
, NULL
, SHGFP_TYPE_CURRENT
, (LPWSTR
)&myDocs
);
330 pos_basename
= file_basename(file
);
334 *(pos_basename
-1) = 0;
335 if(!lstrcmpiW(file
, myDocs
) || (lstrlenW(pos_basename
) > FILELIST_ENTRY_LENGTH
))
337 truncpos1
= pos_basename
;
338 *(pos_basename
-1) = '\\';
342 BOOL morespace
= FALSE
;
344 *(pos_basename
-1) = '\\';
346 for(pos
= file
; pos
< pos_basename
; pos
++)
348 if(*pos
== '\\' || *pos
== '/')
352 if((pos
- file
+ lstrlenW(pos_basename
)) > FILELIST_ENTRY_LENGTH
)
360 if((pos
- file
+ lstrlenW(pos_basename
)) > FILELIST_ENTRY_LENGTH
)
369 for(pos
= pos_basename
; pos
>= truncpos1
; pos
--)
371 if(*pos
== '\\' || *pos
== '/')
373 if((truncpos1
- file
+ lstrlenW(pos_basename
) + pos_basename
- pos
) > FILELIST_ENTRY_LENGTH
)
382 if(truncpos1
== pos_basename
)
383 lstrcatW(out
, pos_basename
);
384 else if(truncpos1
== truncpos2
|| !truncpos2
)
387 truncate_path(file
, out
, truncpos1
, truncpos2
? truncpos2
: (pos_basename
-1));
390 static void registry_read_filelist(HWND hMainWnd
)
394 if(registry_get_handle(&hFileKey
, 0, key_recentfiles
) == ERROR_SUCCESS
)
396 WCHAR itemText
[MAX_PATH
+3], buffer
[MAX_PATH
];
397 /* The menu item name is not the same as the file name, so we need to store
398 the file name here */
399 static WCHAR file1
[MAX_PATH
], file2
[MAX_PATH
], file3
[MAX_PATH
], file4
[MAX_PATH
];
400 WCHAR numFormat
[] = {'&','%','d',' ',0};
401 LPWSTR pFile
[] = {file1
, file2
, file3
, file4
};
402 DWORD pathSize
= MAX_PATH
*sizeof(WCHAR
);
406 HMENU hMenu
= GetMenu(hMainWnd
);
408 mi
.cbSize
= sizeof(MENUITEMINFOW
);
409 mi
.fMask
= MIIM_ID
| MIIM_DATA
| MIIM_STRING
| MIIM_FTYPE
;
410 mi
.fType
= MFT_STRING
;
411 mi
.dwTypeData
= itemText
;
412 mi
.wID
= ID_FILE_RECENT1
;
414 RemoveMenu(hMenu
, ID_FILE_RECENT_SEPARATOR
, MF_BYCOMMAND
);
415 for(i
= 0; i
< FILELIST_ENTRIES
; i
++)
417 wsprintfW(key
, var_file
, i
+1);
418 RemoveMenu(hMenu
, ID_FILE_RECENT1
+i
, MF_BYCOMMAND
);
419 if(RegQueryValueExW(hFileKey
, (LPWSTR
)key
, 0, NULL
, (LPBYTE
)pFile
[i
], &pathSize
)
423 mi
.dwItemData
= (DWORD
)pFile
[i
];
424 wsprintfW(itemText
, numFormat
, i
+1);
426 lstrcpyW(buffer
, pFile
[i
]);
428 format_filelist_filename(buffer
, itemText
);
430 InsertMenuItemW(hMenu
, ID_FILE_EXIT
, FALSE
, &mi
);
432 pathSize
= MAX_PATH
*sizeof(WCHAR
);
434 mi
.fType
= MFT_SEPARATOR
;
435 mi
.fMask
= MIIM_FTYPE
| MIIM_ID
;
436 InsertMenuItemW(hMenu
, ID_FILE_EXIT
, FALSE
, &mi
);
438 RegCloseKey(hFileKey
);
442 static void registry_set_filelist(LPCWSTR newFile
)
447 if(registry_get_handle(&hKey
, &action
, key_recentfiles
) == ERROR_SUCCESS
)
449 LPCWSTR pFiles
[FILELIST_ENTRIES
];
451 HMENU hMenu
= GetMenu(hMainWnd
);
455 mi
.cbSize
= sizeof(MENUITEMINFOW
);
456 mi
.fMask
= MIIM_DATA
;
458 for(i
= 0; i
< FILELIST_ENTRIES
; i
++)
461 for(i
= 0; GetMenuItemInfoW(hMenu
, ID_FILE_RECENT1
+i
, FALSE
, &mi
); i
++)
462 pFiles
[i
] = (LPWSTR
)mi
.dwItemData
;
464 if(lstrcmpiW(newFile
, pFiles
[0]))
466 for(i
= 0; pFiles
[i
] && i
< FILELIST_ENTRIES
; i
++)
468 if(!lstrcmpiW(pFiles
[i
], newFile
))
471 for(j
= 0; pFiles
[j
] && j
< i
; j
++)
473 pFiles
[i
-j
] = pFiles
[i
-j
-1];
485 for(i
= 0; pFiles
[i
] && i
< FILELIST_ENTRIES
-1; i
++)
486 pFiles
[FILELIST_ENTRIES
-1-i
] = pFiles
[FILELIST_ENTRIES
-2-i
];
491 for(i
= 0; pFiles
[i
] && i
< FILELIST_ENTRIES
; i
++)
493 wsprintfW(buffer
, var_file
, i
+1);
494 RegSetValueExW(hKey
, (LPWSTR
)&buffer
, 0, REG_SZ
, (LPBYTE
)pFiles
[i
],
495 (lstrlenW(pFiles
[i
])+1)*sizeof(WCHAR
));
500 registry_read_filelist(hMainWnd
);
503 static BOOL
validate_endptr(LPCSTR endptr
, BOOL units
)
505 if(!endptr
|| !*endptr
)
508 while(*endptr
== ' ')
512 return *endptr
!= '\0';
514 /* FIXME: Allow other units and convert between them */
515 if(!lstrcmpA(endptr
, units_cmA
))
518 return *endptr
!= '\0';
521 static BOOL
number_from_string(LPCWSTR string
, float *num
, BOOL units
)
524 char buffer
[MAX_STRING_LEN
];
525 char *endptr
= buffer
;
527 WideCharToMultiByte(CP_ACP
, 0, string
, -1, buffer
, MAX_STRING_LEN
, NULL
, NULL
);
530 ret
= strtod(buffer
, &endptr
);
532 if((ret
== 0 && errno
!= 0) || endptr
== buffer
|| validate_endptr(endptr
, units
))
542 static void clear_formatting(void)
546 pf
.cbSize
= sizeof(pf
);
547 pf
.dwMask
= PFM_ALIGNMENT
;
548 pf
.wAlignment
= PFA_LEFT
;
549 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
552 static int reg_formatindex(WPARAM format
)
554 return (format
& SF_TEXT
) ? 1 : 0;
557 static int fileformat_number(WPARAM format
)
561 if(format
== SF_TEXT
)
564 } else if (format
== (SF_TEXT
| SF_UNICODE
))
571 static WPARAM
fileformat_flags(int format
)
573 WPARAM flags
[] = { SF_RTF
, SF_TEXT
, SF_TEXT
| SF_UNICODE
};
575 return flags
[format
];
578 static void set_default_font(void)
580 static const WCHAR richTextFont
[] = {'T','i','m','e','s',' ','N','e','w',' ',
581 'R','o','m','a','n',0};
582 static const WCHAR plainTextFont
[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
586 ZeroMemory(&fmt
, sizeof(fmt
));
588 fmt
.cbSize
= sizeof(fmt
);
589 fmt
.dwMask
= CFM_FACE
| CFM_BOLD
| CFM_ITALIC
| CFM_UNDERLINE
;
592 if(fileFormat
& SF_RTF
)
595 font
= plainTextFont
;
597 lstrcpyW(fmt
.szFaceName
, font
);
599 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_DEFAULT
, (LPARAM
)&fmt
);
602 static void update_window(void)
606 GetWindowRect(hMainWnd
, &rect
);
608 (void) OnSize(hMainWnd
, SIZE_RESTORED
, MAKELONG(rect
.bottom
, rect
.right
));
611 static DWORD barState
[2];
613 static BOOL
is_bar_visible(int bandId
)
615 return barState
[reg_formatindex(fileFormat
)] & (1 << bandId
);
618 static void store_bar_state(int bandId
, BOOL show
)
620 int formatIndex
= reg_formatindex(fileFormat
);
623 barState
[formatIndex
] |= (1 << bandId
);
625 barState
[formatIndex
] &= ~(1 << bandId
);
628 static void set_toolbar_state(int bandId
, BOOL show
)
630 HWND hwndReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
632 SendMessageW(hwndReBar
, RB_SHOWBAND
, SendMessageW(hwndReBar
, RB_IDTOINDEX
, bandId
, 0), show
);
634 if(bandId
== BANDID_TOOLBAR
)
636 REBARBANDINFOW rbbinfo
;
637 int index
= SendMessageW(hwndReBar
, RB_IDTOINDEX
, BANDID_FORMATBAR
, 0);
639 rbbinfo
.cbSize
= sizeof(rbbinfo
);
640 rbbinfo
.fMask
= RBBIM_STYLE
;
642 SendMessageW(hwndReBar
, RB_GETBANDINFO
, index
, (LPARAM
)&rbbinfo
);
645 rbbinfo
.fStyle
&= ~RBBS_BREAK
;
647 rbbinfo
.fStyle
|= RBBS_BREAK
;
649 SendMessageW(hwndReBar
, RB_SETBANDINFO
, index
, (LPARAM
)&rbbinfo
);
652 if(bandId
== BANDID_TOOLBAR
|| bandId
== BANDID_FORMATBAR
)
653 store_bar_state(bandId
, show
);
656 static void set_statusbar_state(BOOL show
)
658 HWND hStatusWnd
= GetDlgItem(hMainWnd
, IDC_STATUSBAR
);
660 ShowWindow(hStatusWnd
, show
? SW_SHOW
: SW_HIDE
);
661 store_bar_state(BANDID_STATUSBAR
, show
);
664 static void set_bar_states(void)
666 set_toolbar_state(BANDID_TOOLBAR
, is_bar_visible(BANDID_TOOLBAR
));
667 set_toolbar_state(BANDID_FORMATBAR
, is_bar_visible(BANDID_FORMATBAR
));
668 set_statusbar_state(is_bar_visible(BANDID_STATUSBAR
));
673 static void set_fileformat(WPARAM format
)
681 static void DoOpenFile(LPCWSTR szOpenFileName
)
687 WPARAM format
= SF_TEXT
;
689 hFile
= CreateFileW(szOpenFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
690 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
691 if (hFile
== INVALID_HANDLE_VALUE
)
694 ReadFile(hFile
, fileStart
, 5, &readOut
, NULL
);
695 SetFilePointer(hFile
, 0, NULL
, FILE_BEGIN
);
697 if(readOut
>= 2 && (BYTE
)fileStart
[0] == 0xff && (BYTE
)fileStart
[1] == 0xfe)
699 format
= SF_TEXT
| SF_UNICODE
;
700 SetFilePointer(hFile
, 2, NULL
, FILE_BEGIN
);
701 } else if(readOut
>= 5)
703 static const char header
[] = "{\\rtf";
704 if(!memcmp(header
, fileStart
, 5))
708 es
.dwCookie
= (DWORD_PTR
)hFile
;
709 es
.pfnCallback
= stream_in
;
712 set_fileformat(format
);
713 SendMessageW(hEditorWnd
, EM_STREAMIN
, format
, (LPARAM
)&es
);
717 SetFocus(hEditorWnd
);
719 set_caption(szOpenFileName
);
721 lstrcpyW(wszFileName
, szOpenFileName
);
722 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
723 registry_set_filelist(szOpenFileName
);
724 set_fileformat(format
);
727 static void DoSaveFile(LPCWSTR wszSaveFileName
, WPARAM format
)
733 hFile
= CreateFileW(wszSaveFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
734 FILE_ATTRIBUTE_NORMAL
, NULL
);
736 if(hFile
== INVALID_HANDLE_VALUE
)
739 if(format
== (SF_TEXT
| SF_UNICODE
))
741 static const BYTE unicode
[] = {0xff,0xfe};
743 WriteFile(hFile
, &unicode
, sizeof(unicode
), &writeOut
, 0);
745 if(writeOut
!= sizeof(unicode
))
749 stream
.dwCookie
= (DWORD_PTR
)hFile
;
750 stream
.pfnCallback
= stream_out
;
752 ret
= SendMessageW(hEditorWnd
, EM_STREAMOUT
, format
, (LPARAM
)&stream
);
756 SetFocus(hEditorWnd
);
761 gt
.flags
= GTL_DEFAULT
;
764 if(SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
768 lstrcpyW(wszFileName
, wszSaveFileName
);
769 set_caption(wszFileName
);
770 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
771 set_fileformat(format
);
774 static void DialogSaveFile(void)
778 WCHAR wszFile
[MAX_PATH
] = {'\0'};
779 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
781 ZeroMemory(&sfn
, sizeof(sfn
));
783 sfn
.lStructSize
= sizeof(sfn
);
784 sfn
.Flags
= OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
;
785 sfn
.hwndOwner
= hMainWnd
;
786 sfn
.lpstrFilter
= wszFilter
;
787 sfn
.lpstrFile
= wszFile
;
788 sfn
.nMaxFile
= MAX_PATH
;
789 sfn
.lpstrDefExt
= wszDefExt
;
790 sfn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
792 while(GetSaveFileNameW(&sfn
))
794 if(fileformat_flags(sfn
.nFilterIndex
-1) != SF_RTF
)
796 if(MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_SAVE_LOSEFORMATTING
),
797 wszAppTitle
, MB_YESNO
| MB_ICONEXCLAMATION
) != IDYES
)
802 DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
807 DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
813 static BOOL
prompt_save_changes(void)
818 gt
.flags
= GTL_NUMCHARS
;
820 if(!SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
824 if(!SendMessageW(hEditorWnd
, EM_GETMODIFY
, 0, 0))
829 LPWSTR displayFileName
;
834 displayFileName
= wszDefaultFileName
;
836 displayFileName
= file_basename(wszFileName
);
838 text
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
839 (lstrlenW(displayFileName
)+lstrlenW(wszSaveChanges
))*sizeof(WCHAR
));
844 wsprintfW(text
, wszSaveChanges
, displayFileName
);
846 ret
= MessageBoxW(hMainWnd
, text
, wszAppTitle
, MB_YESNOCANCEL
| MB_ICONEXCLAMATION
);
848 HeapFree(GetProcessHeap(), 0, text
);
857 DoSaveFile(wszFileName
, fileFormat
);
868 static void DialogOpenFile(void)
872 WCHAR wszFile
[MAX_PATH
] = {'\0'};
873 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
875 ZeroMemory(&ofn
, sizeof(ofn
));
877 ofn
.lStructSize
= sizeof(ofn
);
878 ofn
.Flags
= OFN_HIDEREADONLY
| OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
879 ofn
.hwndOwner
= hMainWnd
;
880 ofn
.lpstrFilter
= wszFilter
;
881 ofn
.lpstrFile
= wszFile
;
882 ofn
.nMaxFile
= MAX_PATH
;
883 ofn
.lpstrDefExt
= wszDefExt
;
884 ofn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
886 if(GetOpenFileNameW(&ofn
))
888 if(prompt_save_changes())
889 DoOpenFile(ofn
.lpstrFile
);
893 static LPWSTR
dialog_print_to_file(void)
896 static WCHAR file
[MAX_PATH
] = {'O','U','T','P','U','T','.','P','R','N',0};
897 static const WCHAR defExt
[] = {'P','R','N',0};
899 ZeroMemory(&ofn
, sizeof(ofn
));
901 ofn
.lStructSize
= sizeof(ofn
);
902 ofn
.Flags
= OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
903 ofn
.hwndOwner
= hMainWnd
;
904 ofn
.lpstrFilter
= (LPWSTR
)wszPrintFilter
;
905 ofn
.lpstrFile
= (LPWSTR
)file
;
906 ofn
.nMaxFile
= MAX_PATH
;
907 ofn
.lpstrDefExt
= (LPWSTR
)defExt
;
909 if(GetSaveFileNameW(&ofn
))
915 static LONG
devunits_to_twips(int units
, int dpi
)
917 float ret
= ((float)units
/ (float)dpi
) * (float)567 * 2.54;
921 static int centmm_to_twips(int mm
)
923 return MulDiv(mm
, 567, 1000);
926 static int twips_to_centmm(int twips
)
928 return MulDiv(twips
, 1000, 567);
931 static HGLOBAL devMode
;
932 static HGLOBAL devNames
;
934 static void print(LPPRINTDLGW pd
)
938 int dpiY
, dpiX
, width
, height
;
939 int printedPages
= 0;
942 fr
.hdcTarget
= pd
->hDC
;
944 dpiY
= GetDeviceCaps(fr
.hdc
, LOGPIXELSY
);
945 dpiX
= GetDeviceCaps(fr
.hdc
, LOGPIXELSX
);
946 width
= devunits_to_twips(GetDeviceCaps(fr
.hdc
, PHYSICALWIDTH
), dpiX
);
947 height
= devunits_to_twips(GetDeviceCaps(fr
.hdc
, PHYSICALHEIGHT
), dpiY
);
949 fr
.rc
.left
= margins
.left
;
950 fr
.rc
.right
= width
- margins
.right
;
951 fr
.rc
.top
= margins
.top
;
952 fr
.rc
.bottom
= height
- margins
.bottom
;
954 fr
.rcPage
.right
= width
;
956 fr
.rcPage
.bottom
= height
;
958 ZeroMemory(&di
, sizeof(di
));
959 di
.cbSize
= sizeof(di
);
960 di
.lpszDocName
= (LPWSTR
)wszFileName
;
962 if(pd
->Flags
& PD_PRINTTOFILE
)
964 di
.lpszOutput
= dialog_print_to_file();
969 if(pd
->Flags
& PD_SELECTION
)
971 SendMessageW(hEditorWnd
, EM_EXGETSEL
, 0, (LPARAM
)&fr
.chrg
);
975 gt
.flags
= GTL_DEFAULT
;
978 fr
.chrg
.cpMax
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
980 if(pd
->Flags
& PD_PAGENUMS
)
983 for(i
= 1; i
<= pd
->nToPage
; i
++)
985 if(i
== pd
->nFromPage
)
988 fr
.chrg
.cpMin
= SendMessageW(hEditorWnd
, EM_FORMATRANGE
, TRUE
, (LPARAM
)&fr
);
993 StartDocW(fr
.hdc
, &di
);
996 if(StartPage(fr
.hdc
) <= 0)
999 fr
.chrg
.cpMin
= SendMessageW(hEditorWnd
, EM_FORMATRANGE
, TRUE
, (LPARAM
)&fr
);
1001 if(EndPage(fr
.hdc
) <= 0)
1005 if((pd
->Flags
& PD_PAGENUMS
) && (printedPages
> (pd
->nToPage
- pd
->nFromPage
)))
1008 while(fr
.chrg
.cpMin
< fr
.chrg
.cpMax
);
1011 SendMessageW(hEditorWnd
, EM_FORMATRANGE
, FALSE
, 0);
1014 static void dialog_printsetup(void)
1018 ZeroMemory(&ps
, sizeof(ps
));
1019 ps
.lStructSize
= sizeof(ps
);
1020 ps
.hwndOwner
= hMainWnd
;
1021 ps
.Flags
= PSD_INHUNDREDTHSOFMILLIMETERS
| PSD_MARGINS
;
1022 ps
.rtMargin
.left
= twips_to_centmm(margins
.left
);
1023 ps
.rtMargin
.right
= twips_to_centmm(margins
.right
);
1024 ps
.rtMargin
.top
= twips_to_centmm(margins
.top
);
1025 ps
.rtMargin
.bottom
= twips_to_centmm(margins
.bottom
);
1026 ps
.hDevMode
= devMode
;
1027 ps
.hDevNames
= devNames
;
1029 if(PageSetupDlgW(&ps
))
1031 margins
.left
= centmm_to_twips(ps
.rtMargin
.left
);
1032 margins
.right
= centmm_to_twips(ps
.rtMargin
.right
);
1033 margins
.top
= centmm_to_twips(ps
.rtMargin
.top
);
1034 margins
.bottom
= centmm_to_twips(ps
.rtMargin
.bottom
);
1035 devMode
= ps
.hDevMode
;
1036 devNames
= ps
.hDevNames
;
1040 static void print_quick(void)
1043 ZeroMemory(&pd
, sizeof(pd
));
1045 if(devMode
&& devNames
)
1047 LPDEVNAMES dn
= GlobalLock(devNames
);
1048 LPDEVMODEW dm
= GlobalLock(devMode
);
1049 pd
.hDC
= CreateDCW((LPWSTR
)dn
+ dn
->wDriverOffset
,
1050 (LPWSTR
)dn
+ dn
->wDeviceOffset
, 0, dm
);
1055 ZeroMemory(&pd
, sizeof(pd
));
1056 pd
.lStructSize
= sizeof(pd
);
1057 pd
.Flags
= PD_RETURNDC
| PD_RETURNDEFAULT
;
1058 pd
.hwndOwner
= hMainWnd
;
1059 pd
.hDevMode
= (HGLOBAL
)devMode
;
1063 devMode
= pd
.hDevMode
;
1064 devNames
= pd
.hDevNames
;
1070 static void dialog_print(void)
1076 ZeroMemory(&pd
, sizeof(pd
));
1077 pd
.lStructSize
= sizeof(pd
);
1078 pd
.hwndOwner
= hMainWnd
;
1079 pd
.Flags
= PD_RETURNDC
| PD_USEDEVMODECOPIESANDCOLLATE
;
1082 pd
.hDevMode
= devMode
;
1083 pd
.hDevNames
= devNames
;
1085 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
1087 pd
.Flags
|= PD_NOSELECTION
;
1091 devMode
= pd
.hDevMode
;
1092 devNames
= pd
.hDevNames
;
1097 static void HandleCommandLine(LPWSTR cmdline
)
1102 /* skip white space */
1103 while (*cmdline
== ' ') cmdline
++;
1105 /* skip executable name */
1106 delimiter
= (*cmdline
== '"' ? '"' : ' ');
1108 if (*cmdline
== delimiter
) cmdline
++;
1109 while (*cmdline
&& *cmdline
!= delimiter
) cmdline
++;
1110 if (*cmdline
== delimiter
) cmdline
++;
1112 while (*cmdline
== ' ' || *cmdline
== '-' || *cmdline
== '/')
1116 if (*cmdline
++ == ' ') continue;
1119 if (option
) cmdline
++;
1120 while (*cmdline
== ' ') cmdline
++;
1133 /* file name is passed on the command line */
1134 if (cmdline
[0] == '"')
1137 cmdline
[lstrlenW(cmdline
) - 1] = 0;
1139 DoOpenFile(cmdline
);
1140 InvalidateRect(hMainWnd
, NULL
, FALSE
);
1144 MessageBox(hMainWnd
, "Printing not implemented", "WordPad", MB_OK
);
1147 static LRESULT
handle_findmsg(LPFINDREPLACEW pFr
)
1149 if(pFr
->Flags
& FR_DIALOGTERM
)
1152 pFr
->Flags
= FR_FINDNEXT
;
1154 } else if(pFr
->Flags
& FR_FINDNEXT
)
1156 DWORD flags
= FR_DOWN
;
1158 static CHARRANGE cr
;
1163 HMENU hMenu
= GetMenu(hMainWnd
);
1166 mi
.cbSize
= sizeof(mi
);
1167 mi
.fMask
= MIIM_DATA
;
1169 SetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
1171 gt
.flags
= GTL_NUMCHARS
;
1174 length
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
1176 if(pFr
->lCustData
== -1)
1178 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&startPos
, (LPARAM
)&end
);
1179 cr
.cpMin
= startPos
;
1180 pFr
->lCustData
= startPos
;
1182 if(cr
.cpMin
== length
)
1186 startPos
= pFr
->lCustData
;
1189 if(cr
.cpMax
> length
)
1197 ft
.lpstrText
= pFr
->lpstrFindWhat
;
1199 if(pFr
->Flags
& FR_MATCHCASE
)
1200 flags
|= FR_MATCHCASE
;
1201 if(pFr
->Flags
& FR_WHOLEWORD
)
1202 flags
|= FR_WHOLEWORD
;
1204 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTW
, (WPARAM
)flags
, (LPARAM
)&ft
);
1208 if(cr
.cpMax
== length
&& cr
.cpMax
!= startPos
)
1210 ft
.chrg
.cpMin
= cr
.cpMin
= 0;
1211 ft
.chrg
.cpMax
= cr
.cpMax
= startPos
;
1213 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTW
, (WPARAM
)flags
, (LPARAM
)&ft
);
1219 pFr
->lCustData
= -1;
1220 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED
), wszAppTitle
,
1221 MB_OK
| MB_ICONASTERISK
);
1224 end
= ret
+ lstrlenW(pFr
->lpstrFindWhat
);
1226 SendMessageW(hEditorWnd
, EM_SETSEL
, (WPARAM
)ret
, (LPARAM
)end
);
1227 SendMessageW(hEditorWnd
, EM_SCROLLCARET
, 0, 0);
1234 static void dialog_find(LPFINDREPLACEW fr
)
1236 static WCHAR findBuffer
[MAX_STRING_LEN
];
1238 ZeroMemory(fr
, sizeof(FINDREPLACEW
));
1239 fr
->lStructSize
= sizeof(FINDREPLACEW
);
1240 fr
->hwndOwner
= hMainWnd
;
1241 fr
->Flags
= FR_HIDEUPDOWN
;
1242 fr
->lpstrFindWhat
= findBuffer
;
1244 fr
->wFindWhatLen
= MAX_STRING_LEN
*sizeof(WCHAR
);
1246 hFindWnd
= FindTextW(fr
);
1249 static void registry_read_options(void)
1252 DWORD size
= sizeof(RECT
);
1254 if(registry_get_handle(&hKey
, 0, key_options
) != ERROR_SUCCESS
||
1255 RegQueryValueExW(hKey
, var_pagemargin
, 0, NULL
, (LPBYTE
)&margins
,
1256 &size
) != ERROR_SUCCESS
|| size
!= sizeof(RECT
))
1259 margins
.bottom
= 1417;
1260 margins
.left
= 1757;
1261 margins
.right
= 1757;
1267 static void registry_read_formatopts(int index
, LPCWSTR key
)
1271 BOOL fetched
= FALSE
;
1272 barState
[index
] = 0;
1274 if(registry_get_handle(&hKey
, &action
, key
) != ERROR_SUCCESS
)
1277 if(action
== REG_OPENED_EXISTING_KEY
)
1279 DWORD size
= sizeof(DWORD
);
1281 if(RegQueryValueExW(hKey
, var_barstate0
, 0, NULL
, (LPBYTE
)&barState
[index
],
1282 &size
) == ERROR_SUCCESS
)
1287 barState
[index
] = (1 << BANDID_TOOLBAR
) | (1 << BANDID_FORMATBAR
) | (1 << BANDID_RULER
) | (1 << BANDID_STATUSBAR
);
1292 static void registry_read_formatopts_all(void)
1294 registry_read_formatopts(reg_formatindex(SF_RTF
), key_rtf
);
1295 registry_read_formatopts(reg_formatindex(SF_TEXT
), key_text
);
1298 static void registry_set_formatopts(int index
, LPCWSTR key
)
1303 if(registry_get_handle(&hKey
, &action
, key
) == ERROR_SUCCESS
)
1305 RegSetValueExW(hKey
, var_barstate0
, 0, REG_DWORD
, (LPBYTE
)&barState
[index
],
1312 static void registry_set_formatopts_all(void)
1314 registry_set_formatopts(reg_formatindex(SF_RTF
), key_rtf
);
1315 registry_set_formatopts(reg_formatindex(SF_TEXT
), key_text
);
1318 static int current_units_to_twips(float number
)
1320 int twips
= (int)(number
* 567);
1324 static void append_current_units(LPWSTR buffer
)
1326 static const WCHAR space
[] = {' '};
1327 lstrcatW(buffer
, space
);
1328 lstrcatW(buffer
, units_cmW
);
1331 static void number_with_units(LPWSTR buffer
, int number
)
1333 float converted
= (float)number
/ 567;
1334 char string
[MAX_STRING_LEN
];
1336 sprintf(string
, "%.2f ", converted
);
1337 lstrcatA(string
, units_cmA
);
1338 MultiByteToWideChar(CP_ACP
, 0, string
, -1, buffer
, MAX_STRING_LEN
);
1341 BOOL CALLBACK
datetime_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1347 WCHAR buffer
[MAX_STRING_LEN
];
1349 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
1352 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, 0, (LPWSTR
)&buffer
,
1354 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1355 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, 0, (LPWSTR
)&buffer
,
1357 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1358 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, 0, (LPWSTR
)&buffer
, MAX_STRING_LEN
);
1359 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1361 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1366 switch(LOWORD(wParam
))
1371 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
1373 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1377 WCHAR buffer
[MAX_STRING_LEN
];
1378 SendMessageW(hListWnd
, LB_GETTEXT
, index
, (LPARAM
)&buffer
);
1379 SendMessageW(hEditorWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)&buffer
);
1385 EndDialog(hWnd
, wParam
);
1392 BOOL CALLBACK
newfile_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1398 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
1399 WCHAR buffer
[MAX_STRING_LEN
];
1400 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1402 LoadStringW(hInstance
, STRING_NEWFILE_RICHTEXT
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
1403 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1404 LoadStringW(hInstance
, STRING_NEWFILE_TXT
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
1405 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1406 LoadStringW(hInstance
, STRING_NEWFILE_TXT_UNICODE
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
1407 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1409 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1414 switch(LOWORD(wParam
))
1419 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1420 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1423 EndDialog(hWnd
, MAKELONG(fileformat_flags(index
),0));
1428 EndDialog(hWnd
, MAKELONG(ID_NEWFILE_ABORT
,0));
1435 static INT_PTR CALLBACK
paraformat_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1441 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
,
1443 WCHAR buffer
[MAX_STRING_LEN
];
1444 HWND hListWnd
= GetDlgItem(hWnd
, IDC_PARA_ALIGN
);
1445 HWND hLeftWnd
= GetDlgItem(hWnd
, IDC_PARA_LEFT
);
1446 HWND hRightWnd
= GetDlgItem(hWnd
, IDC_PARA_RIGHT
);
1447 HWND hFirstWnd
= GetDlgItem(hWnd
, IDC_PARA_FIRST
);
1451 LoadStringW(hInstance
, STRING_ALIGN_LEFT
, buffer
,
1453 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1454 LoadStringW(hInstance
, STRING_ALIGN_RIGHT
, buffer
,
1456 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1457 LoadStringW(hInstance
, STRING_ALIGN_CENTER
, buffer
,
1459 SendMessageW(hListWnd
, CB_ADDSTRING
, 0, (LPARAM
)buffer
);
1461 pf
.cbSize
= sizeof(pf
);
1462 pf
.dwMask
= PFM_ALIGNMENT
| PFM_OFFSET
| PFM_RIGHTINDENT
|
1464 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1466 if(pf
.wAlignment
== PFA_RIGHT
)
1468 else if(pf
.wAlignment
== PFA_CENTER
)
1471 SendMessageW(hListWnd
, CB_SETCURSEL
, index
, 0);
1473 number_with_units(buffer
, pf
.dxOffset
);
1474 SetWindowTextW(hLeftWnd
, buffer
);
1475 number_with_units(buffer
, pf
.dxRightIndent
);
1476 SetWindowTextW(hRightWnd
, buffer
);
1477 number_with_units(buffer
, pf
.dxStartIndent
- pf
.dxOffset
);
1478 SetWindowTextW(hFirstWnd
, buffer
);
1483 switch(LOWORD(wParam
))
1487 HWND hLeftWnd
= GetDlgItem(hWnd
, IDC_PARA_LEFT
);
1488 HWND hRightWnd
= GetDlgItem(hWnd
, IDC_PARA_RIGHT
);
1489 HWND hFirstWnd
= GetDlgItem(hWnd
, IDC_PARA_FIRST
);
1490 WCHAR buffer
[MAX_STRING_LEN
];
1495 GetWindowTextW(hLeftWnd
, buffer
, MAX_STRING_LEN
);
1496 if(number_from_string(buffer
, &num
, TRUE
))
1498 pf
.dxOffset
= current_units_to_twips(num
);
1499 GetWindowTextW(hRightWnd
, buffer
, MAX_STRING_LEN
);
1500 if(number_from_string(buffer
, &num
, TRUE
))
1502 pf
.dxRightIndent
= current_units_to_twips(num
);
1503 GetWindowTextW(hFirstWnd
, buffer
, MAX_STRING_LEN
);
1504 if(number_from_string(buffer
, &num
, TRUE
))
1506 pf
.dxStartIndent
= current_units_to_twips(num
);
1510 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
1511 wszAppTitle
, MB_OK
| MB_ICONASTERISK
);
1515 pf
.dxStartIndent
= pf
.dxStartIndent
+ pf
.dxOffset
;
1516 pf
.cbSize
= sizeof(pf
);
1517 pf
.dwMask
= PFM_OFFSET
| PFM_OFFSETINDENT
| PFM_RIGHTINDENT
;
1518 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1524 EndDialog(hWnd
, wParam
);
1531 static INT_PTR CALLBACK
tabstops_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1537 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1539 WCHAR buffer
[MAX_STRING_LEN
];
1542 pf
.cbSize
= sizeof(pf
);
1543 pf
.dwMask
= PFM_TABSTOPS
;
1544 SendMessageW(hEditorWnd
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1545 SendMessageW(hTabWnd
, CB_LIMITTEXT
, MAX_STRING_LEN
-1, 0);
1547 for(i
= 0; i
< pf
.cTabCount
; i
++)
1549 number_with_units(buffer
, pf
.rgxTabs
[i
]);
1550 SendMessageW(hTabWnd
, CB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1557 switch(LOWORD(wParam
))
1561 HWND hTabWnd
= (HWND
)lParam
;
1562 HWND hAddWnd
= GetDlgItem(hWnd
, ID_TAB_ADD
);
1563 HWND hDelWnd
= GetDlgItem(hWnd
, ID_TAB_DEL
);
1564 HWND hEmptyWnd
= GetDlgItem(hWnd
, ID_TAB_EMPTY
);
1566 if(GetWindowTextLengthW(hTabWnd
))
1567 EnableWindow(hAddWnd
, TRUE
);
1569 EnableWindow(hAddWnd
, FALSE
);
1571 if(SendMessageW(hTabWnd
, CB_GETCOUNT
, 0, 0))
1573 EnableWindow(hEmptyWnd
, TRUE
);
1575 if(SendMessageW(hTabWnd
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
1576 EnableWindow(hDelWnd
, FALSE
);
1578 EnableWindow(hDelWnd
, TRUE
);
1581 EnableWindow(hEmptyWnd
, FALSE
);
1588 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1589 WCHAR buffer
[MAX_STRING_LEN
];
1591 GetWindowTextW(hTabWnd
, buffer
, MAX_STRING_LEN
);
1592 append_current_units(buffer
);
1594 if(SendMessageW(hTabWnd
, CB_FINDSTRINGEXACT
, -1, (LPARAM
)&buffer
) == CB_ERR
)
1598 if(!number_from_string(buffer
, &number
, TRUE
))
1600 MessageBoxW(hWnd
, MAKEINTRESOURCEW(STRING_INVALID_NUMBER
),
1601 wszAppTitle
, MB_OK
| MB_ICONINFORMATION
);
1604 SendMessageW(hTabWnd
, CB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1605 SetWindowTextW(hTabWnd
, 0);
1614 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1616 ret
= SendMessageW(hTabWnd
, CB_GETCURSEL
, 0, 0);
1618 SendMessageW(hTabWnd
, CB_DELETESTRING
, ret
, 0);
1624 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1625 SendMessageW(hTabWnd
, CB_RESETCONTENT
, 0, 0);
1632 HWND hTabWnd
= GetDlgItem(hWnd
, IDC_TABSTOPS
);
1634 WCHAR buffer
[MAX_STRING_LEN
];
1638 pf
.cbSize
= sizeof(pf
);
1639 pf
.dwMask
= PFM_TABSTOPS
;
1641 for(i
= 0; SendMessageW(hTabWnd
, CB_GETLBTEXT
, i
,
1642 (LPARAM
)&buffer
) != CB_ERR
&&
1643 i
< MAX_TAB_STOPS
; i
++)
1645 number_from_string(buffer
, &number
, TRUE
);
1646 pf
.rgxTabs
[i
] = current_units_to_twips(number
);
1649 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1653 EndDialog(hWnd
, wParam
);
1660 static LRESULT
OnCreate( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1662 HWND hToolBarWnd
, hFormatBarWnd
, hReBarWnd
;
1663 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1666 int nStdBitmaps
= 0;
1669 static const WCHAR wszRichEditDll
[] = {'R','I','C','H','E','D','2','0','.','D','L','L','\0'};
1670 static const WCHAR wszRichEditText
[] = {'R','i','c','h','E','d','i','t',' ','t','e','x','t','\0'};
1672 CreateStatusWindowW(CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
, wszRichEditText
, hWnd
, IDC_STATUSBAR
);
1674 hReBarWnd
= CreateWindowExW(WS_EX_TOOLWINDOW
, REBARCLASSNAMEW
, NULL
,
1675 CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|RBS_VARHEIGHT
|CCS_TOP
,
1676 CW_USEDEFAULT
, CW_USEDEFAULT
, 0, 0, hWnd
, (HMENU
)IDC_REBAR
, hInstance
, NULL
);
1678 rbi
.cbSize
= sizeof(rbi
);
1681 if(!SendMessageW(hReBarWnd
, RB_SETBARINFO
, 0, (LPARAM
)&rbi
))
1684 hToolBarWnd
= CreateToolbarEx(hReBarWnd
, CCS_NOPARENTALIGN
|CCS_NOMOVEY
|WS_VISIBLE
|WS_CHILD
|TBSTYLE_TOOLTIPS
|TBSTYLE_BUTTON
,
1686 1, hInstance
, IDB_TOOLBAR
,
1688 24, 24, 16, 16, sizeof(TBBUTTON
));
1690 ab
.hInst
= HINST_COMMCTRL
;
1691 ab
.nID
= IDB_STD_SMALL_COLOR
;
1692 nStdBitmaps
= SendMessageW(hToolBarWnd
, TB_ADDBITMAP
, 0, (LPARAM
)&ab
);
1694 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILENEW
, ID_FILE_NEW
);
1695 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILEOPEN
, ID_FILE_OPEN
);
1696 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILESAVE
, ID_FILE_SAVE
);
1697 AddSeparator(hToolBarWnd
);
1698 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINT
, ID_PRINT_QUICK
);
1699 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINTPRE
, ID_PREVIEW
);
1700 AddSeparator(hToolBarWnd
);
1701 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FIND
, ID_FIND
);
1702 AddSeparator(hToolBarWnd
);
1703 AddButton(hToolBarWnd
, nStdBitmaps
+STD_CUT
, ID_EDIT_CUT
);
1704 AddButton(hToolBarWnd
, nStdBitmaps
+STD_COPY
, ID_EDIT_COPY
);
1705 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PASTE
, ID_EDIT_PASTE
);
1706 AddButton(hToolBarWnd
, nStdBitmaps
+STD_UNDO
, ID_EDIT_UNDO
);
1707 AddButton(hToolBarWnd
, nStdBitmaps
+STD_REDOW
, ID_EDIT_REDO
);
1708 AddSeparator(hToolBarWnd
);
1709 AddButton(hToolBarWnd
, 0, ID_DATETIME
);
1711 SendMessageW(hToolBarWnd
, TB_AUTOSIZE
, 0, 0);
1713 rbb
.cbSize
= sizeof(rbb
);
1714 rbb
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
| RBBIM_STYLE
| RBBIM_ID
;
1715 rbb
.fStyle
= RBBS_CHILDEDGE
| RBBS_BREAK
| RBBS_NOGRIPPER
;
1717 rbb
.hwndChild
= hToolBarWnd
;
1719 rbb
.cyChild
= rbb
.cyMinChild
= HIWORD(SendMessageW(hToolBarWnd
, TB_GETBUTTONSIZE
, 0, 0));
1720 rbb
.wID
= BANDID_TOOLBAR
;
1722 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1724 hFormatBarWnd
= CreateToolbarEx(hReBarWnd
,
1725 CCS_NOPARENTALIGN
| CCS_NOMOVEY
| WS_VISIBLE
| TBSTYLE_TOOLTIPS
| TBSTYLE_BUTTON
,
1726 IDC_FORMATBAR
, 7, hInstance
, IDB_FORMATBAR
, NULL
, 0, 16, 16, 16, 16, sizeof(TBBUTTON
));
1728 AddButton(hFormatBarWnd
, 0, ID_FORMAT_BOLD
);
1729 AddButton(hFormatBarWnd
, 1, ID_FORMAT_ITALIC
);
1730 AddButton(hFormatBarWnd
, 2, ID_FORMAT_UNDERLINE
);
1731 AddSeparator(hFormatBarWnd
);
1732 AddButton(hFormatBarWnd
, 3, ID_ALIGN_LEFT
);
1733 AddButton(hFormatBarWnd
, 4, ID_ALIGN_CENTER
);
1734 AddButton(hFormatBarWnd
, 5, ID_ALIGN_RIGHT
);
1735 AddSeparator(hFormatBarWnd
);
1736 AddButton(hFormatBarWnd
, 6, ID_BULLET
);
1738 SendMessageW(hFormatBarWnd
, TB_AUTOSIZE
, 0, 0);
1740 rbb
.hwndChild
= hFormatBarWnd
;
1741 rbb
.wID
= BANDID_FORMATBAR
;
1743 SendMessageW(hReBarWnd
, RB_INSERTBAND
, -1, (LPARAM
)&rbb
);
1745 hDLL
= LoadLibraryW(wszRichEditDll
);
1748 MessageBoxW(hWnd
, MAKEINTRESOURCEW(STRING_LOAD_RICHED_FAILED
), wszAppTitle
,
1749 MB_OK
| MB_ICONEXCLAMATION
);
1753 hEditorWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, wszRichEditClass
, NULL
,
1754 WS_CHILD
|WS_VISIBLE
|ES_MULTILINE
|ES_AUTOVSCROLL
|ES_WANTRETURN
|WS_VSCROLL
,
1755 0, 0, 1000, 100, hWnd
, (HMENU
)IDC_EDITOR
, hInstance
, NULL
);
1759 fprintf(stderr
, "Error code %u\n", GetLastError());
1764 SetFocus(hEditorWnd
);
1765 SendMessageW(hEditorWnd
, EM_SETEVENTMASK
, 0, ENM_SELCHANGE
);
1770 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
1772 ID_FINDMSGSTRING
= RegisterWindowMessageW(FINDMSGSTRINGW
);
1774 registry_read_filelist(hWnd
);
1775 registry_read_formatopts_all();
1776 registry_read_options();
1777 DragAcceptFiles(hWnd
, TRUE
);
1782 static LRESULT
OnUser( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1784 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1785 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
1786 HWND hwndToolBar
= GetDlgItem(hwndReBar
, IDC_TOOLBAR
);
1787 HWND hwndFormatBar
= GetDlgItem(hwndReBar
, IDC_FORMATBAR
);
1793 ZeroMemory(&fmt
, sizeof(fmt
));
1794 fmt
.cbSize
= sizeof(fmt
);
1796 ZeroMemory(&pf
, sizeof(pf
));
1797 pf
.cbSize
= sizeof(pf
);
1799 gt
.flags
= GTL_NUMCHARS
;
1802 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_FIND
,
1803 SendMessageW(hwndEditor
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0) ? 1 : 0);
1805 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, TRUE
, (LPARAM
)&fmt
);
1807 SendMessageW(hwndEditor
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
1808 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_UNDO
,
1809 SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0));
1810 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_REDO
,
1811 SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0));
1812 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_CUT
, from
== to
? 0 : 1);
1813 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_COPY
, from
== to
? 0 : 1);
1815 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_BOLD
, (fmt
.dwMask
& CFM_BOLD
) &&
1816 (fmt
.dwEffects
& CFE_BOLD
));
1817 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_BOLD
, !(fmt
.dwMask
& CFM_BOLD
));
1818 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_ITALIC
, (fmt
.dwMask
& CFM_ITALIC
) &&
1819 (fmt
.dwEffects
& CFE_ITALIC
));
1820 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_ITALIC
, !(fmt
.dwMask
& CFM_ITALIC
));
1821 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_UNDERLINE
, (fmt
.dwMask
& CFM_UNDERLINE
) &&
1822 (fmt
.dwEffects
& CFE_UNDERLINE
));
1823 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_UNDERLINE
, !(fmt
.dwMask
& CFM_UNDERLINE
));
1825 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1826 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_LEFT
, (pf
.wAlignment
== PFA_LEFT
));
1827 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_CENTER
, (pf
.wAlignment
== PFA_CENTER
));
1828 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_RIGHT
, (pf
.wAlignment
== PFA_RIGHT
));
1830 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_BULLET
, (pf
.wNumbering
& PFN_BULLET
));
1834 static LRESULT
OnNotify( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1836 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1837 NMHDR
*pHdr
= (NMHDR
*)lParam
;
1839 if (pHdr
->hwndFrom
!= hwndEditor
)
1842 if (pHdr
->code
== EN_SELCHANGE
)
1844 SELCHANGE
*pSC
= (SELCHANGE
*)lParam
;
1847 sprintf( buf
,"selection = %d..%d, line count=%ld",
1848 pSC
->chrg
.cpMin
, pSC
->chrg
.cpMax
,
1849 SendMessage(hwndEditor
, EM_GETLINECOUNT
, 0, 0));
1850 SetWindowText(GetDlgItem(hWnd
, IDC_STATUSBAR
), buf
);
1851 SendMessage(hWnd
, WM_USER
, 0, 0);
1857 static LRESULT
OnCommand( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1859 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1860 static FINDREPLACEW findreplace
;
1862 if ((HWND
)lParam
== hwndEditor
)
1865 switch(LOWORD(wParam
))
1869 PostMessageW(hWnd
, WM_CLOSE
, 0, 0);
1874 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1875 int ret
= DialogBox(hInstance
, MAKEINTRESOURCE(IDD_NEWFILE
), hWnd
,
1876 (DLGPROC
)newfile_proc
);
1878 if(ret
!= ID_NEWFILE_ABORT
)
1880 if(prompt_save_changes())
1885 wszFileName
[0] = '\0';
1889 st
.flags
= ST_DEFAULT
;
1891 SendMessageW(hEditorWnd
, EM_SETTEXTEX
, (WPARAM
)&st
, 0);
1893 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
1894 set_fileformat(ret
);
1907 DoSaveFile(wszFileName
, fileFormat
);
1912 case ID_FILE_SAVEAS
:
1916 case ID_FILE_RECENT1
:
1917 case ID_FILE_RECENT2
:
1918 case ID_FILE_RECENT3
:
1919 case ID_FILE_RECENT4
:
1921 HMENU hMenu
= GetMenu(hWnd
);
1924 mi
.cbSize
= sizeof(MENUITEMINFOW
);
1925 mi
.fMask
= MIIM_DATA
;
1926 if(GetMenuItemInfoW(hMenu
, LOWORD(wParam
), FALSE
, &mi
))
1927 DoOpenFile((LPWSTR
)mi
.dwItemData
);
1932 dialog_find(&findreplace
);
1936 handle_findmsg(&findreplace
);
1943 case ID_PRINT_QUICK
:
1949 static const WCHAR wszNotImplemented
[] = {'N','o','t',' ',
1950 'i','m','p','l','e','m','e','n','t','e','d','\0'};
1951 MessageBoxW(hWnd
, wszNotImplemented
, wszAppTitle
, MB_OK
);
1956 dialog_printsetup();
1959 case ID_FORMAT_BOLD
:
1960 case ID_FORMAT_ITALIC
:
1961 case ID_FORMAT_UNDERLINE
:
1964 int mask
= CFM_BOLD
;
1965 if (LOWORD(wParam
) == ID_FORMAT_ITALIC
) mask
= CFM_ITALIC
;
1966 if (LOWORD(wParam
) == ID_FORMAT_UNDERLINE
) mask
= CFM_UNDERLINE
;
1968 ZeroMemory(&fmt
, sizeof(fmt
));
1969 fmt
.cbSize
= sizeof(fmt
);
1970 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
1971 if (!(fmt
.dwMask
&mask
))
1972 fmt
.dwEffects
|= mask
;
1974 fmt
.dwEffects
^= mask
;
1976 SendMessageW(hwndEditor
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
1981 PostMessageW(hwndEditor
, WM_CUT
, 0, 0);
1985 PostMessageW(hwndEditor
, WM_COPY
, 0, 0);
1989 PostMessageW(hwndEditor
, WM_PASTE
, 0, 0);
1993 PostMessageW(hwndEditor
, WM_CLEAR
, 0, 0);
1996 case ID_EDIT_SELECTALL
:
1998 CHARRANGE range
= {0, -1};
1999 SendMessageW(hwndEditor
, EM_EXSETSEL
, 0, (LPARAM
)&range
);
2000 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2004 case ID_EDIT_GETTEXT
:
2006 int nLen
= GetWindowTextLengthW(hwndEditor
);
2007 LPWSTR data
= HeapAlloc( GetProcessHeap(), 0, (nLen
+1)*sizeof(WCHAR
) );
2010 GetWindowTextW(hwndEditor
, data
, nLen
+1);
2011 MessageBoxW(NULL
, data
, xszAppTitle
, MB_OK
);
2013 HeapFree( GetProcessHeap(), 0, data
);
2014 data
= HeapAlloc(GetProcessHeap(), 0, (nLen
+1)*sizeof(WCHAR
));
2016 tr
.chrg
.cpMax
= nLen
;
2017 tr
.lpstrText
= data
;
2018 SendMessage (hwndEditor
, EM_GETTEXTRANGE
, 0, (LPARAM
)&tr
);
2019 MessageBoxW(NULL
, data
, xszAppTitle
, MB_OK
);
2020 HeapFree( GetProcessHeap(), 0, data
);
2022 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2026 case ID_EDIT_CHARFORMAT
:
2027 case ID_EDIT_DEFCHARFORMAT
:
2031 ZeroMemory(&cf
, sizeof(cf
));
2032 cf
.cbSize
= sizeof(cf
);
2034 i
= SendMessageW(hwndEditor
, EM_GETCHARFORMAT
,
2035 LOWORD(wParam
) == ID_EDIT_CHARFORMAT
, (LPARAM
)&cf
);
2039 case ID_EDIT_PARAFORMAT
:
2042 ZeroMemory(&pf
, sizeof(pf
));
2043 pf
.cbSize
= sizeof(pf
);
2044 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2048 case ID_EDIT_SELECTIONINFO
:
2050 CHARRANGE range
= {0, -1};
2054 SendMessage(hwndEditor
, EM_EXGETSEL
, 0, (LPARAM
)&range
);
2055 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
) * (range
.cpMax
-range
.cpMin
+1));
2056 SendMessage(hwndEditor
, EM_GETSELTEXT
, 0, (LPARAM
)data
);
2057 sprintf(buf
, "Start = %d, End = %d", range
.cpMin
, range
.cpMax
);
2058 MessageBoxA(hWnd
, buf
, "Editor", MB_OK
);
2059 MessageBoxW(hWnd
, data
, xszAppTitle
, MB_OK
);
2060 HeapFree( GetProcessHeap(), 0, data
);
2061 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
2065 case ID_EDIT_READONLY
:
2067 long nStyle
= GetWindowLong(hwndEditor
, GWL_STYLE
);
2068 if (nStyle
& ES_READONLY
)
2069 SendMessageW(hwndEditor
, EM_SETREADONLY
, 0, 0);
2071 SendMessageW(hwndEditor
, EM_SETREADONLY
, 1, 0);
2075 case ID_EDIT_MODIFIED
:
2076 if (SendMessageW(hwndEditor
, EM_GETMODIFY
, 0, 0))
2077 SendMessageW(hwndEditor
, EM_SETMODIFY
, 0, 0);
2079 SendMessageW(hwndEditor
, EM_SETMODIFY
, 1, 0);
2083 SendMessageW(hwndEditor
, EM_UNDO
, 0, 0);
2087 SendMessageW(hwndEditor
, EM_REDO
, 0, 0);
2094 pf
.cbSize
= sizeof(pf
);
2095 pf
.dwMask
= PFM_NUMBERING
;
2096 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2098 pf
.dwMask
|= PFM_OFFSET
;
2100 if(pf
.wNumbering
== PFN_BULLET
)
2106 pf
.wNumbering
= PFN_BULLET
;
2110 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
2115 case ID_ALIGN_CENTER
:
2116 case ID_ALIGN_RIGHT
:
2120 pf
.cbSize
= sizeof(pf
);
2121 pf
.dwMask
= PFM_ALIGNMENT
;
2122 switch(LOWORD(wParam
)) {
2123 case ID_ALIGN_LEFT
: pf
.wAlignment
= PFA_LEFT
; break;
2124 case ID_ALIGN_CENTER
: pf
.wAlignment
= PFA_CENTER
; break;
2125 case ID_ALIGN_RIGHT
: pf
.wAlignment
= PFA_RIGHT
; break;
2127 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
2132 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 1, 0);
2136 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 0, RGB(255,255,192));
2139 case ID_TOGGLE_TOOLBAR
:
2140 set_toolbar_state(BANDID_TOOLBAR
, !is_bar_visible(BANDID_TOOLBAR
));
2144 case ID_TOGGLE_FORMATBAR
:
2145 set_toolbar_state(BANDID_FORMATBAR
, !is_bar_visible(BANDID_FORMATBAR
));
2149 case ID_TOGGLE_STATUSBAR
:
2150 set_statusbar_state(!is_bar_visible(BANDID_STATUSBAR
));
2156 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
2157 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_DATETIME
), hWnd
, (DLGPROC
)datetime_proc
);
2163 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
2164 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_PARAFORMAT
), hWnd
,
2171 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
2172 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_TABSTOPS
), hWnd
, tabstops_proc
);
2177 SendMessageW(hwndEditor
, WM_COMMAND
, wParam
, lParam
);
2183 static LRESULT
OnInitPopupMenu( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
2185 HMENU hMenu
= (HMENU
)wParam
;
2186 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2187 HWND hwndStatus
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
2189 int nAlignment
= -1;
2195 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&selFrom
, (LPARAM
)&selTo
);
2196 EnableMenuItem(hMenu
, ID_EDIT_COPY
, MF_BYCOMMAND
|(selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
2197 EnableMenuItem(hMenu
, ID_EDIT_CUT
, MF_BYCOMMAND
|(selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
2199 pf
.cbSize
= sizeof(PARAFORMAT
);
2200 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
2201 CheckMenuItem(hMenu
, ID_EDIT_READONLY
,
2202 MF_BYCOMMAND
|(GetWindowLong(hwndEditor
, GWL_STYLE
)&ES_READONLY
? MF_CHECKED
: MF_UNCHECKED
));
2203 CheckMenuItem(hMenu
, ID_EDIT_MODIFIED
,
2204 MF_BYCOMMAND
|(SendMessage(hwndEditor
, EM_GETMODIFY
, 0, 0) ? MF_CHECKED
: MF_UNCHECKED
));
2205 if (pf
.dwMask
& PFM_ALIGNMENT
)
2206 nAlignment
= pf
.wAlignment
;
2207 CheckMenuItem(hMenu
, ID_ALIGN_LEFT
, MF_BYCOMMAND
|(nAlignment
== PFA_LEFT
) ?
2208 MF_CHECKED
: MF_UNCHECKED
);
2209 CheckMenuItem(hMenu
, ID_ALIGN_CENTER
, MF_BYCOMMAND
|(nAlignment
== PFA_CENTER
) ?
2210 MF_CHECKED
: MF_UNCHECKED
);
2211 CheckMenuItem(hMenu
, ID_ALIGN_RIGHT
, MF_BYCOMMAND
|(nAlignment
== PFA_RIGHT
) ?
2212 MF_CHECKED
: MF_UNCHECKED
);
2213 CheckMenuItem(hMenu
, ID_BULLET
, MF_BYCOMMAND
| ((pf
.wNumbering
== PFN_BULLET
) ?
2214 MF_CHECKED
: MF_UNCHECKED
));
2215 EnableMenuItem(hMenu
, ID_EDIT_UNDO
, MF_BYCOMMAND
|(SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0)) ?
2216 MF_ENABLED
: MF_GRAYED
);
2217 EnableMenuItem(hMenu
, ID_EDIT_REDO
, MF_BYCOMMAND
|(SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0)) ?
2218 MF_ENABLED
: MF_GRAYED
);
2220 CheckMenuItem(hMenu
, ID_TOGGLE_TOOLBAR
, MF_BYCOMMAND
|(is_bar_visible(BANDID_TOOLBAR
)) ?
2221 MF_CHECKED
: MF_UNCHECKED
);
2223 CheckMenuItem(hMenu
, ID_TOGGLE_FORMATBAR
, MF_BYCOMMAND
|(is_bar_visible(BANDID_FORMATBAR
)) ?
2224 MF_CHECKED
: MF_UNCHECKED
);
2226 CheckMenuItem(hMenu
, ID_TOGGLE_STATUSBAR
, MF_BYCOMMAND
|IsWindowVisible(hwndStatus
) ?
2227 MF_CHECKED
: MF_UNCHECKED
);
2229 gt
.flags
= GTL_NUMCHARS
;
2231 textLength
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
2232 EnableMenuItem(hMenu
, ID_FIND
, MF_BYCOMMAND
|(textLength
? MF_ENABLED
: MF_GRAYED
));
2234 mi
.cbSize
= sizeof(mi
);
2235 mi
.fMask
= MIIM_DATA
;
2237 GetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
2239 EnableMenuItem(hMenu
, ID_FIND_NEXT
, MF_BYCOMMAND
|((textLength
&& mi
.dwItemData
) ?
2240 MF_ENABLED
: MF_GRAYED
));
2244 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
2246 int nStatusSize
= 0;
2248 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
2249 HWND hwndStatusBar
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
2250 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
2251 int rebarHeight
= 0;
2256 SendMessageW(hwndStatusBar
, WM_SIZE
, 0, 0);
2257 if (IsWindowVisible(hwndStatusBar
))
2259 GetClientRect(hwndStatusBar
, &rc
);
2260 nStatusSize
= rc
.bottom
- rc
.top
;
2268 if(!is_bar_visible(BANDID_TOOLBAR
))
2271 if(!is_bar_visible(BANDID_FORMATBAR
))
2274 rebarHeight
= rebarRows
? SendMessageW(hwndReBar
, RB_GETBARHEIGHT
, 0, 0) : 0;
2276 rc
.top
= rc
.left
= 0;
2277 rc
.bottom
= rebarHeight
;
2278 rc
.right
= LOWORD(lParam
);
2279 SendMessageW(hwndReBar
, RB_SIZETORECT
, 0, (LPARAM
)&rc
);
2283 GetClientRect(hWnd
, &rc
);
2284 MoveWindow(hwndEditor
, 0, rebarHeight
, rc
.right
, rc
.bottom
-nStatusSize
-rebarHeight
, TRUE
);
2287 return DefWindowProcW(hWnd
, WM_SIZE
, wParam
, lParam
);
2290 static LRESULT CALLBACK
WndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2292 if(msg
== ID_FINDMSGSTRING
)
2293 return handle_findmsg((LPFINDREPLACEW
)lParam
);
2298 return OnCreate( hWnd
, wParam
, lParam
);
2301 return OnUser( hWnd
, wParam
, lParam
);
2304 return OnNotify( hWnd
, wParam
, lParam
);
2307 return OnCommand( hWnd
, wParam
, lParam
);
2314 if(prompt_save_changes())
2316 registry_set_options();
2317 registry_set_formatopts_all();
2324 SetFocus(GetDlgItem(hWnd
, IDC_EDITOR
));
2327 case WM_INITMENUPOPUP
:
2328 return OnInitPopupMenu( hWnd
, wParam
, lParam
);
2331 return OnSize( hWnd
, wParam
, lParam
);
2335 WCHAR file
[MAX_PATH
];
2336 DragQueryFileW((HDROP
)wParam
, 0, file
, MAX_PATH
);
2337 DragFinish((HDROP
)wParam
);
2339 if(prompt_save_changes())
2345 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
2351 int CALLBACK
WinMain(HINSTANCE hInstance
, HINSTANCE hOldInstance
, LPSTR szCmdParagraph
, int res
)
2353 INITCOMMONCONTROLSEX classes
= {8, ICC_BAR_CLASSES
|ICC_COOL_CLASSES
};
2358 static const WCHAR wszAccelTable
[] = {'M','A','I','N','A','C','C','E','L',
2359 'T','A','B','L','E','\0'};
2361 InitCommonControlsEx(&classes
);
2363 hAccel
= LoadAcceleratorsW(hInstance
, wszAccelTable
);
2365 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2366 wc
.lpfnWndProc
= WndProc
;
2369 wc
.hInstance
= hInstance
;
2370 wc
.hIcon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_WORDPAD
));
2371 wc
.hCursor
= LoadCursor(NULL
, IDC_IBEAM
);
2372 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
2373 wc
.lpszMenuName
= xszMainMenu
;
2374 wc
.lpszClassName
= wszMainWndClass
;
2375 RegisterClassW(&wc
);
2377 rc
= registry_read_winrect();
2378 hMainWnd
= CreateWindowExW(0, wszMainWndClass
, wszAppTitle
, WS_OVERLAPPEDWINDOW
,
2379 rc
.left
, rc
.top
, rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, NULL
, NULL
, hInstance
, NULL
);
2380 ShowWindow(hMainWnd
, SW_SHOWDEFAULT
);
2385 HandleCommandLine(GetCommandLineW());
2387 while(GetMessageW(&msg
,0,0,0))
2389 if (IsDialogMessage(hFindWnd
, &msg
))
2392 if (TranslateAcceleratorW(hMainWnd
, hAccel
, &msg
))
2394 TranslateMessage(&msg
);
2395 DispatchMessageW(&msg
);
2396 if (!PeekMessageW(&msg
, 0, 0, 0, PM_NOREMOVE
))
2397 SendMessageW(hMainWnd
, WM_USER
, 0, 0);