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
40 static const WCHAR xszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
41 static const WCHAR xszMainMenu
[] = {'M','A','I','N','M','E','N','U',0};
43 static const WCHAR wszRichEditClass
[] = {'R','I','C','H','E','D','I','T','2','0','W',0};
44 static const WCHAR wszMainWndClass
[] = {'W','O','R','D','P','A','D','T','O','P',0};
45 static const WCHAR wszAppTitle
[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
47 static const WCHAR key_recentfiles
[] = {'R','e','c','e','n','t',' ','f','i','l','e',
48 ' ','l','i','s','t',0};
49 static const WCHAR key_options
[] = {'O','p','t','i','o','n','s',0};
51 static const WCHAR var_file
[] = {'F','i','l','e','%','d',0};
52 static const WCHAR var_framerect
[] = {'F','r','a','m','e','R','e','c','t',0};
56 static HWND hEditorWnd
;
59 static UINT ID_FINDMSGSTRING
;
61 static WCHAR wszFilter
[MAX_STRING_LEN
*4+6*3+5];
62 static WCHAR wszDefaultFileName
[MAX_STRING_LEN
];
63 static WCHAR wszSaveChanges
[MAX_STRING_LEN
];
65 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
67 /* Load string resources */
68 static void DoLoadStrings(void)
71 static const WCHAR files_rtf
[] = {'*','.','r','t','f','\0'};
72 static const WCHAR files_txt
[] = {'*','.','t','x','t','\0'};
73 static const WCHAR files_all
[] = {'*','.','*','\0'};
74 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
76 LoadStringW(hInstance
, STRING_RICHTEXT_FILES_RTF
, p
, MAX_STRING_LEN
);
78 lstrcpyW(p
, files_rtf
);
80 LoadStringW(hInstance
, STRING_TEXT_FILES_TXT
, p
, MAX_STRING_LEN
);
82 lstrcpyW(p
, files_txt
);
84 LoadStringW(hInstance
, STRING_TEXT_FILES_UNICODE_TXT
, p
, MAX_STRING_LEN
);
86 lstrcpyW(p
, files_txt
);
88 LoadStringW(hInstance
, STRING_ALL_FILES
, p
, MAX_STRING_LEN
);
90 lstrcpyW(p
, files_all
);
94 p
= wszDefaultFileName
;
95 LoadStringW(hInstance
, STRING_DEFAULT_FILENAME
, p
, MAX_STRING_LEN
);
98 LoadStringW(hInstance
, STRING_PROMPT_SAVE_CHANGES
, p
, MAX_STRING_LEN
);
101 static void AddButton(HWND hwndToolBar
, int nImage
, int nCommand
)
105 ZeroMemory(&button
, sizeof(button
));
106 button
.iBitmap
= nImage
;
107 button
.idCommand
= nCommand
;
108 button
.fsState
= TBSTATE_ENABLED
;
109 button
.fsStyle
= TBSTYLE_BUTTON
;
112 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
115 static void AddSeparator(HWND hwndToolBar
)
119 ZeroMemory(&button
, sizeof(button
));
121 button
.idCommand
= 0;
123 button
.fsStyle
= TBSTYLE_SEP
;
126 SendMessageW(hwndToolBar
, TB_ADDBUTTONSW
, 1, (LPARAM
)&button
);
129 static DWORD CALLBACK
stream_in(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
131 HANDLE hFile
= (HANDLE
)cookie
;
134 if(!ReadFile(hFile
, buffer
, cb
, &read
, 0))
142 static DWORD CALLBACK
stream_out(DWORD_PTR cookie
, LPBYTE buffer
, LONG cb
, LONG
*pcb
)
146 HANDLE hFile
= (HANDLE
)cookie
;
148 ret
= WriteFile(hFile
, buffer
, cb
, &written
, 0);
150 if(!ret
|| (cb
!= written
))
159 static LPWSTR
file_basename(LPWSTR path
)
161 LPWSTR pos
= path
+ lstrlenW(path
);
165 if(*pos
== '\\' || *pos
== '/')
175 static WCHAR wszFileName
[MAX_PATH
];
176 static WPARAM fileFormat
= SF_RTF
;
178 static void set_caption(LPCWSTR wszNewFileName
)
180 static const WCHAR wszSeparator
[] = {' ','-',' '};
185 wszNewFileName
= wszDefaultFileName
;
187 wszNewFileName
= file_basename((LPWSTR
)wszNewFileName
);
189 wszCaption
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
190 lstrlenW(wszNewFileName
)*sizeof(WCHAR
)+sizeof(wszSeparator
)+sizeof(wszAppTitle
));
195 memcpy(wszCaption
, wszNewFileName
, lstrlenW(wszNewFileName
)*sizeof(WCHAR
));
196 length
+= lstrlenW(wszNewFileName
);
197 memcpy(wszCaption
+ length
, wszSeparator
, sizeof(wszSeparator
));
198 length
+= sizeof(wszSeparator
) / sizeof(WCHAR
);
199 memcpy(wszCaption
+ length
, wszAppTitle
, sizeof(wszAppTitle
));
201 SetWindowTextW(hMainWnd
, wszCaption
);
203 HeapFree(GetProcessHeap(), 0, wszCaption
);
206 static LRESULT
registry_get_handle(HKEY
*hKey
, LPDWORD action
, LPCWSTR subKey
)
209 static const WCHAR wszProgramKey
[] = {'S','o','f','t','w','a','r','e','\\',
210 'M','i','c','r','o','s','o','f','t','\\',
211 'W','i','n','d','o','w','s','\\',
212 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
213 'A','p','p','l','e','t','s','\\',
214 'W','o','r','d','p','a','d',0};
215 LPWSTR key
= (LPWSTR
)wszProgramKey
;
219 WCHAR backslash
[] = {'\\',0};
220 key
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
221 (lstrlenW(wszProgramKey
)+lstrlenW(subKey
)+lstrlenW(backslash
)+1)
227 lstrcpyW(key
, wszProgramKey
);
228 lstrcatW(key
, backslash
);
229 lstrcatW(key
, subKey
);
234 ret
= RegCreateKeyExW(HKEY_CURRENT_USER
, key
, 0, NULL
, REG_OPTION_NON_VOLATILE
,
235 KEY_READ
| KEY_WRITE
, NULL
, hKey
, action
);
238 ret
= RegOpenKeyExW(HKEY_CURRENT_USER
, key
, 0, KEY_READ
| KEY_WRITE
, hKey
);
242 HeapFree(GetProcessHeap(), 0, key
);
247 static void registry_set_winrect(void)
252 if(registry_get_handle(&hKey
, &action
, (LPWSTR
)key_options
) == ERROR_SUCCESS
)
256 GetWindowRect(hMainWnd
, &rc
);
258 RegSetValueExW(hKey
, var_framerect
, 0, REG_BINARY
, (LPBYTE
)&rc
, sizeof(RECT
));
262 static RECT
registry_read_winrect(void)
266 DWORD size
= sizeof(RECT
);
268 ZeroMemory(&rc
, sizeof(RECT
));
269 if(registry_get_handle(&hKey
, 0, (LPWSTR
)key_options
) != ERROR_SUCCESS
||
270 RegQueryValueExW(hKey
, var_framerect
, 0, NULL
, (LPBYTE
)&rc
, &size
) !=
271 ERROR_SUCCESS
|| size
!= sizeof(RECT
))
283 static void truncate_path(LPWSTR file
, LPWSTR out
, LPWSTR pos1
, LPWSTR pos2
)
285 static const WCHAR dots
[] = {'.','.','.',0};
294 static void format_filelist_filename(LPWSTR file
, LPWSTR out
)
297 LPWSTR truncpos1
, truncpos2
;
298 WCHAR myDocs
[MAX_STRING_LEN
];
300 SHGetFolderPathW(NULL
, CSIDL_PERSONAL
, NULL
, SHGFP_TYPE_CURRENT
, (LPWSTR
)&myDocs
);
301 pos_basename
= file_basename(file
);
305 *(pos_basename
-1) = 0;
306 if(!lstrcmpiW(file
, myDocs
) || (lstrlenW(pos_basename
) > FILELIST_ENTRY_LENGTH
))
308 truncpos1
= pos_basename
;
309 *(pos_basename
-1) = '\\';
313 BOOL morespace
= FALSE
;
315 *(pos_basename
-1) = '\\';
317 for(pos
= file
; pos
< pos_basename
; pos
++)
319 if(*pos
== '\\' || *pos
== '/')
323 if((pos
- file
+ lstrlenW(pos_basename
)) > FILELIST_ENTRY_LENGTH
)
331 if((pos
- file
+ lstrlenW(pos_basename
)) > FILELIST_ENTRY_LENGTH
)
340 for(pos
= pos_basename
; pos
>= truncpos1
; pos
--)
342 if(*pos
== '\\' || *pos
== '/')
344 if((truncpos1
- file
+ lstrlenW(pos_basename
) + pos_basename
- pos
) > FILELIST_ENTRY_LENGTH
)
353 if(truncpos1
== pos_basename
)
354 lstrcatW(out
, pos_basename
);
355 else if(truncpos1
== truncpos2
|| !truncpos2
)
358 truncate_path(file
, out
, truncpos1
, truncpos2
? truncpos2
: (pos_basename
-1));
361 static void registry_read_filelist(HWND hMainWnd
)
365 if(registry_get_handle(&hFileKey
, 0, key_recentfiles
) == ERROR_SUCCESS
)
367 WCHAR itemText
[MAX_PATH
+3], buffer
[MAX_PATH
];
368 /* The menu item name is not the same as the file name, so we need to store
369 the file name here */
370 static WCHAR file1
[MAX_PATH
], file2
[MAX_PATH
], file3
[MAX_PATH
], file4
[MAX_PATH
];
371 WCHAR numFormat
[] = {'&','%','d',' ',0};
372 LPWSTR pFile
[] = {file1
, file2
, file3
, file4
};
373 DWORD pathSize
= MAX_PATH
*sizeof(WCHAR
);
377 HMENU hMenu
= GetMenu(hMainWnd
);
379 mi
.cbSize
= sizeof(MENUITEMINFOW
);
380 mi
.fMask
= MIIM_ID
| MIIM_DATA
| MIIM_STRING
| MIIM_FTYPE
;
381 mi
.fType
= MFT_STRING
;
382 mi
.dwTypeData
= itemText
;
383 mi
.wID
= ID_FILE_RECENT1
;
385 RemoveMenu(hMenu
, ID_FILE_RECENT_SEPARATOR
, MF_BYCOMMAND
);
386 for(i
= 0; i
< FILELIST_ENTRIES
; i
++)
388 wsprintfW(key
, var_file
, i
+1);
389 RemoveMenu(hMenu
, ID_FILE_RECENT1
+i
, MF_BYCOMMAND
);
390 if(RegQueryValueExW(hFileKey
, (LPWSTR
)key
, 0, NULL
, (LPBYTE
)pFile
[i
], &pathSize
)
394 mi
.dwItemData
= (DWORD
)pFile
[i
];
395 wsprintfW(itemText
, numFormat
, i
+1);
397 lstrcpyW(buffer
, pFile
[i
]);
399 format_filelist_filename(buffer
, itemText
);
401 InsertMenuItemW(hMenu
, ID_FILE_EXIT
, FALSE
, &mi
);
403 pathSize
= MAX_PATH
*sizeof(WCHAR
);
405 mi
.fType
= MFT_SEPARATOR
;
406 mi
.fMask
= MIIM_FTYPE
| MIIM_ID
;
407 InsertMenuItemW(hMenu
, ID_FILE_EXIT
, FALSE
, &mi
);
409 RegCloseKey(hFileKey
);
413 static void registry_set_filelist(LPCWSTR newFile
)
418 if(registry_get_handle(&hKey
, &action
, key_recentfiles
) == ERROR_SUCCESS
)
420 LPCWSTR pFiles
[FILELIST_ENTRIES
];
422 HMENU hMenu
= GetMenu(hMainWnd
);
426 mi
.cbSize
= sizeof(MENUITEMINFOW
);
427 mi
.fMask
= MIIM_DATA
;
429 for(i
= 0; i
< FILELIST_ENTRIES
; i
++)
432 for(i
= 0; GetMenuItemInfoW(hMenu
, ID_FILE_RECENT1
+i
, FALSE
, &mi
); i
++)
433 pFiles
[i
] = (LPWSTR
)mi
.dwItemData
;
435 if(lstrcmpiW(newFile
, pFiles
[0]))
437 for(i
= 0; pFiles
[i
] && i
< FILELIST_ENTRIES
; i
++)
439 if(!lstrcmpiW(pFiles
[i
], newFile
))
442 for(j
= 0; pFiles
[j
] && j
< i
; j
++)
444 pFiles
[i
-j
] = pFiles
[i
-j
-1];
456 for(i
= 0; pFiles
[i
] && i
< FILELIST_ENTRIES
-1; i
++)
457 pFiles
[FILELIST_ENTRIES
-1-i
] = pFiles
[FILELIST_ENTRIES
-2-i
];
462 for(i
= 0; pFiles
[i
] && i
< FILELIST_ENTRIES
; i
++)
464 wsprintfW(buffer
, var_file
, i
+1);
465 RegSetValueExW(hKey
, (LPWSTR
)&buffer
, 0, REG_SZ
, (LPBYTE
)pFiles
[i
],
466 (lstrlenW(pFiles
[i
])+1)*sizeof(WCHAR
));
471 registry_read_filelist(hMainWnd
);
474 static void clear_formatting(void)
478 pf
.cbSize
= sizeof(pf
);
479 pf
.dwMask
= PFM_ALIGNMENT
;
480 pf
.wAlignment
= PFA_LEFT
;
481 SendMessageW(hEditorWnd
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
484 static int fileformat_number(WPARAM format
)
488 if(format
== SF_TEXT
)
491 } else if (format
== (SF_TEXT
| SF_UNICODE
))
498 static WPARAM
fileformat_flags(int format
)
500 WPARAM flags
[] = { SF_RTF
, SF_TEXT
, SF_TEXT
| SF_UNICODE
};
502 return flags
[format
];
505 static void set_fileformat(WPARAM format
)
510 static void DoOpenFile(LPCWSTR szOpenFileName
)
516 WPARAM format
= SF_TEXT
;
518 hFile
= CreateFileW(szOpenFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
519 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
520 if (hFile
== INVALID_HANDLE_VALUE
)
523 ReadFile(hFile
, fileStart
, 5, &readOut
, NULL
);
524 SetFilePointer(hFile
, 0, NULL
, FILE_BEGIN
);
526 if(readOut
>= 2 && (BYTE
)fileStart
[0] == 0xff && (BYTE
)fileStart
[1] == 0xfe)
528 format
= SF_TEXT
| SF_UNICODE
;
529 SetFilePointer(hFile
, 2, NULL
, FILE_BEGIN
);
530 } else if(readOut
>= 5)
532 static const char header
[] = "{\\rtf";
533 if(!memcmp(header
, fileStart
, 5))
537 es
.dwCookie
= (DWORD_PTR
)hFile
;
538 es
.pfnCallback
= stream_in
;
541 SendMessageW(hEditorWnd
, EM_STREAMIN
, format
, (LPARAM
)&es
);
545 SetFocus(hEditorWnd
);
547 set_caption(szOpenFileName
);
549 lstrcpyW(wszFileName
, szOpenFileName
);
550 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
551 registry_set_filelist(szOpenFileName
);
552 set_fileformat(format
);
555 static void DoSaveFile(LPCWSTR wszSaveFileName
, WPARAM format
)
561 hFile
= CreateFileW(wszSaveFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
562 FILE_ATTRIBUTE_NORMAL
, NULL
);
564 if(hFile
== INVALID_HANDLE_VALUE
)
567 if(format
== (SF_TEXT
| SF_UNICODE
))
569 static const BYTE unicode
[] = {0xff,0xfe};
571 WriteFile(hFile
, &unicode
, sizeof(unicode
), &writeOut
, 0);
573 if(writeOut
!= sizeof(unicode
))
577 stream
.dwCookie
= (DWORD_PTR
)hFile
;
578 stream
.pfnCallback
= stream_out
;
580 ret
= SendMessageW(hEditorWnd
, EM_STREAMOUT
, format
, (LPARAM
)&stream
);
584 SetFocus(hEditorWnd
);
589 gt
.flags
= GTL_DEFAULT
;
592 if(SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
596 lstrcpyW(wszFileName
, wszSaveFileName
);
597 set_caption(wszFileName
);
598 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
599 set_fileformat(format
);
602 static void DialogSaveFile(void)
606 WCHAR wszFile
[MAX_PATH
] = {'\0'};
607 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
609 ZeroMemory(&sfn
, sizeof(sfn
));
611 sfn
.lStructSize
= sizeof(sfn
);
612 sfn
.Flags
= OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
;
613 sfn
.hwndOwner
= hMainWnd
;
614 sfn
.lpstrFilter
= wszFilter
;
615 sfn
.lpstrFile
= wszFile
;
616 sfn
.nMaxFile
= MAX_PATH
;
617 sfn
.lpstrDefExt
= wszDefExt
;
618 sfn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
620 while(GetSaveFileNameW(&sfn
))
622 if(fileformat_flags(sfn
.nFilterIndex
-1) != SF_RTF
)
624 if(MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_SAVE_LOSEFORMATTING
),
625 wszAppTitle
, MB_YESNO
| MB_ICONEXCLAMATION
) != IDYES
)
630 DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
635 DoSaveFile(sfn
.lpstrFile
, fileformat_flags(sfn
.nFilterIndex
-1));
641 static BOOL
prompt_save_changes(void)
646 gt
.flags
= GTL_NUMCHARS
;
648 if(!SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0))
652 if(!SendMessageW(hEditorWnd
, EM_GETMODIFY
, 0, 0))
657 LPWSTR displayFileName
;
662 displayFileName
= wszDefaultFileName
;
664 displayFileName
= file_basename(wszFileName
);
666 text
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
667 (lstrlenW(displayFileName
)+lstrlenW(wszSaveChanges
))*sizeof(WCHAR
));
672 wsprintfW(text
, wszSaveChanges
, displayFileName
);
674 ret
= MessageBoxW(hMainWnd
, text
, wszAppTitle
, MB_YESNOCANCEL
| MB_ICONEXCLAMATION
);
676 HeapFree(GetProcessHeap(), 0, text
);
685 DoSaveFile(wszFileName
, fileFormat
);
696 static void DialogOpenFile(void)
700 WCHAR wszFile
[MAX_PATH
] = {'\0'};
701 static const WCHAR wszDefExt
[] = {'r','t','f','\0'};
703 ZeroMemory(&ofn
, sizeof(ofn
));
705 ofn
.lStructSize
= sizeof(ofn
);
706 ofn
.Flags
= OFN_HIDEREADONLY
| OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
;
707 ofn
.hwndOwner
= hMainWnd
;
708 ofn
.lpstrFilter
= wszFilter
;
709 ofn
.lpstrFile
= wszFile
;
710 ofn
.nMaxFile
= MAX_PATH
;
711 ofn
.lpstrDefExt
= wszDefExt
;
712 ofn
.nFilterIndex
= fileformat_number(fileFormat
)+1;
714 if(GetOpenFileNameW(&ofn
))
716 if(prompt_save_changes())
717 DoOpenFile(ofn
.lpstrFile
);
721 static void HandleCommandLine(LPWSTR cmdline
)
726 /* skip white space */
727 while (*cmdline
== ' ') cmdline
++;
729 /* skip executable name */
730 delimiter
= (*cmdline
== '"' ? '"' : ' ');
732 if (*cmdline
== delimiter
) cmdline
++;
733 while (*cmdline
&& *cmdline
!= delimiter
) cmdline
++;
734 if (*cmdline
== delimiter
) cmdline
++;
736 while (*cmdline
== ' ' || *cmdline
== '-' || *cmdline
== '/')
740 if (*cmdline
++ == ' ') continue;
743 if (option
) cmdline
++;
744 while (*cmdline
== ' ') cmdline
++;
757 /* file name is passed on the command line */
758 if (cmdline
[0] == '"')
761 cmdline
[lstrlenW(cmdline
) - 1] = 0;
764 InvalidateRect(hMainWnd
, NULL
, FALSE
);
768 MessageBox(hMainWnd
, "Printing not implemented", "WordPad", MB_OK
);
771 static LRESULT
handle_findmsg(LPFINDREPLACEW pFr
)
773 if(pFr
->Flags
& FR_DIALOGTERM
)
776 pFr
->Flags
= FR_FINDNEXT
;
778 } else if(pFr
->Flags
& FR_FINDNEXT
)
780 DWORD flags
= FR_DOWN
;
787 HMENU hMenu
= GetMenu(hMainWnd
);
790 mi
.cbSize
= sizeof(mi
);
791 mi
.fMask
= MIIM_DATA
;
793 SetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
795 gt
.flags
= GTL_NUMCHARS
;
798 length
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
800 if(pFr
->lCustData
== -1)
802 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&startPos
, (LPARAM
)&end
);
804 pFr
->lCustData
= startPos
;
806 if(cr
.cpMin
== length
)
810 startPos
= pFr
->lCustData
;
813 if(cr
.cpMax
> length
)
821 ft
.lpstrText
= pFr
->lpstrFindWhat
;
823 if(pFr
->Flags
& FR_MATCHCASE
)
824 flags
|= FR_MATCHCASE
;
825 if(pFr
->Flags
& FR_WHOLEWORD
)
826 flags
|= FR_WHOLEWORD
;
828 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTW
, (WPARAM
)flags
, (LPARAM
)&ft
);
832 if(cr
.cpMax
== length
&& cr
.cpMax
!= startPos
)
834 ft
.chrg
.cpMin
= cr
.cpMin
= 0;
835 ft
.chrg
.cpMax
= cr
.cpMax
= startPos
;
837 ret
= SendMessageW(hEditorWnd
, EM_FINDTEXTW
, (WPARAM
)flags
, (LPARAM
)&ft
);
844 MessageBoxW(hMainWnd
, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED
), wszAppTitle
,
845 MB_OK
| MB_ICONASTERISK
);
848 end
= ret
+ lstrlenW(pFr
->lpstrFindWhat
);
850 SendMessageW(hEditorWnd
, EM_SETSEL
, (WPARAM
)ret
, (LPARAM
)end
);
851 SendMessageW(hEditorWnd
, EM_SCROLLCARET
, 0, 0);
858 static void dialog_find(LPFINDREPLACEW fr
)
860 static WCHAR findBuffer
[MAX_STRING_LEN
];
862 ZeroMemory(fr
, sizeof(FINDREPLACEW
));
863 fr
->lStructSize
= sizeof(FINDREPLACEW
);
864 fr
->hwndOwner
= hMainWnd
;
865 fr
->Flags
= FR_HIDEUPDOWN
;
866 fr
->lpstrFindWhat
= findBuffer
;
868 fr
->wFindWhatLen
= MAX_STRING_LEN
*sizeof(WCHAR
);
870 hFindWnd
= FindTextW(fr
);
874 static void DoDefaultFont(void)
876 static const WCHAR szFaceName
[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0};
879 ZeroMemory(&fmt
, sizeof(fmt
));
881 fmt
.cbSize
= sizeof(fmt
);
882 fmt
.dwMask
= CFM_FACE
| CFM_BOLD
| CFM_ITALIC
| CFM_UNDERLINE
;
885 lstrcpyW(fmt
.szFaceName
, szFaceName
);
887 SendMessageW(hEditorWnd
, EM_SETCHARFORMAT
, SCF_DEFAULT
, (LPARAM
)&fmt
);
890 static void update_window(void)
894 GetWindowRect(hMainWnd
, &rect
);
896 (void) OnSize(hMainWnd
, SIZE_RESTORED
, MAKELONG(rect
.bottom
, rect
.right
));
899 static void toggle_toolbar(int bandId
)
901 HWND hwndReBar
= GetDlgItem(hMainWnd
, IDC_REBAR
);
902 REBARBANDINFOW rbbinfo
;
908 rbbinfo
.cbSize
= sizeof(rbbinfo
);
909 rbbinfo
.fMask
= RBBIM_STYLE
| RBBIM_SIZE
;
911 SendMessageW(hwndReBar
, RB_GETBANDINFO
, bandId
, (LPARAM
)&rbbinfo
);
913 if(rbbinfo
.fStyle
& RBBS_HIDDEN
)
916 SendMessageW(hwndReBar
, RB_SHOWBAND
, bandId
, hide
? 0 : 1);
918 if(bandId
== BANDID_TOOLBAR
)
920 rbbinfo
.fMask
^= RBBIM_SIZE
;
922 SendMessageW(hwndReBar
, RB_GETBANDINFO
, BANDID_FORMATBAR
, (LPARAM
)&rbbinfo
);
925 rbbinfo
.fStyle
^= RBBS_BREAK
;
927 rbbinfo
.fStyle
|= RBBS_BREAK
;
929 SendMessageW(hwndReBar
, RB_SETBANDINFO
, BANDID_FORMATBAR
, (LPARAM
)&rbbinfo
);
933 BOOL CALLBACK
datetime_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
939 WCHAR buffer
[MAX_STRING_LEN
];
941 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
944 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &st
, 0, (LPWSTR
)&buffer
,
946 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
947 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, 0, (LPWSTR
)&buffer
,
949 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
950 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, 0, (LPWSTR
)&buffer
, MAX_STRING_LEN
);
951 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
953 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
958 switch(LOWORD(wParam
))
963 HWND hListWnd
= GetDlgItem(hWnd
, IDC_DATETIME
);
965 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
969 WCHAR buffer
[MAX_STRING_LEN
];
970 SendMessageW(hListWnd
, LB_GETTEXT
, index
, (LPARAM
)&buffer
);
971 SendMessageW(hEditorWnd
, EM_REPLACESEL
, TRUE
, (LPARAM
)&buffer
);
977 EndDialog(hWnd
, wParam
);
984 BOOL CALLBACK
newfile_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
990 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hMainWnd
, GWLP_HINSTANCE
);
991 WCHAR buffer
[MAX_STRING_LEN
];
992 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
994 LoadStringW(hInstance
, STRING_NEWFILE_RICHTEXT
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
995 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
996 LoadStringW(hInstance
, STRING_NEWFILE_TXT
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
997 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
998 LoadStringW(hInstance
, STRING_NEWFILE_TXT_UNICODE
, (LPWSTR
)buffer
, MAX_STRING_LEN
);
999 SendMessageW(hListWnd
, LB_ADDSTRING
, 0, (LPARAM
)&buffer
);
1001 SendMessageW(hListWnd
, LB_SETSEL
, TRUE
, 0);
1006 switch(LOWORD(wParam
))
1011 HWND hListWnd
= GetDlgItem(hWnd
, IDC_NEWFILE
);
1012 index
= SendMessageW(hListWnd
, LB_GETCURSEL
, 0, 0);
1015 EndDialog(hWnd
, MAKELONG(fileformat_flags(index
),0));
1020 EndDialog(hWnd
, MAKELONG(ID_NEWFILE_ABORT
,0));
1027 static LRESULT
OnCreate( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1029 HWND hToolBarWnd
, hFormatBarWnd
, hReBarWnd
;
1030 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1033 int nStdBitmaps
= 0;
1036 static const WCHAR wszRichEditDll
[] = {'R','I','C','H','E','D','2','0','.','D','L','L','\0'};
1037 static const WCHAR wszRichEditText
[] = {'R','i','c','h','E','d','i','t',' ','t','e','x','t','\0'};
1039 CreateStatusWindowW(CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
, wszRichEditText
, hWnd
, IDC_STATUSBAR
);
1041 hReBarWnd
= CreateWindowExW(WS_EX_TOOLWINDOW
, REBARCLASSNAMEW
, NULL
,
1042 CCS_NODIVIDER
|WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|RBS_VARHEIGHT
|CCS_TOP
,
1043 CW_USEDEFAULT
, CW_USEDEFAULT
, 0, 0, hWnd
, (HMENU
)IDC_REBAR
, hInstance
, NULL
);
1045 rbi
.cbSize
= sizeof(rbi
);
1048 if(!SendMessageW(hReBarWnd
, RB_SETBARINFO
, 0, (LPARAM
)&rbi
))
1051 hToolBarWnd
= CreateToolbarEx(hReBarWnd
, CCS_NOPARENTALIGN
|CCS_NOMOVEY
|WS_VISIBLE
|WS_CHILD
|TBSTYLE_TOOLTIPS
|TBSTYLE_BUTTON
,
1053 1, hInstance
, IDB_TOOLBAR
,
1055 24, 24, 16, 16, sizeof(TBBUTTON
));
1057 ab
.hInst
= HINST_COMMCTRL
;
1058 ab
.nID
= IDB_STD_SMALL_COLOR
;
1059 nStdBitmaps
= SendMessageW(hToolBarWnd
, TB_ADDBITMAP
, 0, (LPARAM
)&ab
);
1061 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILENEW
, ID_FILE_NEW
);
1062 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILEOPEN
, ID_FILE_OPEN
);
1063 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FILESAVE
, ID_FILE_SAVE
);
1064 AddSeparator(hToolBarWnd
);
1065 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINT
, ID_PRINT
);
1066 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PRINTPRE
, ID_PREVIEW
);
1067 AddSeparator(hToolBarWnd
);
1068 AddButton(hToolBarWnd
, nStdBitmaps
+STD_FIND
, ID_FIND
);
1069 AddSeparator(hToolBarWnd
);
1070 AddButton(hToolBarWnd
, nStdBitmaps
+STD_CUT
, ID_EDIT_CUT
);
1071 AddButton(hToolBarWnd
, nStdBitmaps
+STD_COPY
, ID_EDIT_COPY
);
1072 AddButton(hToolBarWnd
, nStdBitmaps
+STD_PASTE
, ID_EDIT_PASTE
);
1073 AddButton(hToolBarWnd
, nStdBitmaps
+STD_UNDO
, ID_EDIT_UNDO
);
1074 AddButton(hToolBarWnd
, nStdBitmaps
+STD_REDOW
, ID_EDIT_REDO
);
1075 AddSeparator(hToolBarWnd
);
1076 AddButton(hToolBarWnd
, 0, ID_DATETIME
);
1078 SendMessageW(hToolBarWnd
, TB_AUTOSIZE
, 0, 0);
1080 rbb
.cbSize
= sizeof(rbb
);
1081 rbb
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
| RBBIM_STYLE
;
1082 rbb
.fStyle
= RBBS_CHILDEDGE
| RBBS_BREAK
| RBBS_NOGRIPPER
;
1084 rbb
.hwndChild
= hToolBarWnd
;
1086 rbb
.cyChild
= rbb
.cyMinChild
= HIWORD(SendMessageW(hToolBarWnd
, TB_GETBUTTONSIZE
, 0, 0));
1088 SendMessageW(hReBarWnd
, RB_INSERTBAND
, BANDID_TOOLBAR
, (LPARAM
)&rbb
);
1090 hFormatBarWnd
= CreateToolbarEx(hReBarWnd
,
1091 CCS_NOPARENTALIGN
| CCS_NOMOVEY
| WS_VISIBLE
| TBSTYLE_TOOLTIPS
| TBSTYLE_BUTTON
,
1092 IDC_FORMATBAR
, 7, hInstance
, IDB_FORMATBAR
, NULL
, 0, 16, 16, 16, 16, sizeof(TBBUTTON
));
1094 AddButton(hFormatBarWnd
, 0, ID_FORMAT_BOLD
);
1095 AddButton(hFormatBarWnd
, 1, ID_FORMAT_ITALIC
);
1096 AddButton(hFormatBarWnd
, 2, ID_FORMAT_UNDERLINE
);
1097 AddSeparator(hFormatBarWnd
);
1098 AddButton(hFormatBarWnd
, 3, ID_ALIGN_LEFT
);
1099 AddButton(hFormatBarWnd
, 4, ID_ALIGN_CENTER
);
1100 AddButton(hFormatBarWnd
, 5, ID_ALIGN_RIGHT
);
1101 AddSeparator(hFormatBarWnd
);
1102 AddButton(hFormatBarWnd
, 6, ID_BULLET
);
1104 SendMessageW(hFormatBarWnd
, TB_AUTOSIZE
, 0, 0);
1106 rbb
.hwndChild
= hFormatBarWnd
;
1108 SendMessageW(hReBarWnd
, RB_INSERTBAND
, BANDID_FORMATBAR
, (LPARAM
)&rbb
);
1110 hDLL
= LoadLibraryW(wszRichEditDll
);
1113 MessageBoxW(hWnd
, MAKEINTRESOURCEW(STRING_LOAD_RICHED_FAILED
), wszAppTitle
,
1114 MB_OK
| MB_ICONEXCLAMATION
);
1118 hEditorWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, wszRichEditClass
, NULL
,
1119 WS_CHILD
|WS_VISIBLE
|ES_MULTILINE
|ES_AUTOVSCROLL
|ES_WANTRETURN
|WS_VSCROLL
,
1120 0, 0, 1000, 100, hWnd
, (HMENU
)IDC_EDITOR
, hInstance
, NULL
);
1124 fprintf(stderr
, "Error code %u\n", GetLastError());
1129 SetFocus(hEditorWnd
);
1130 SendMessageW(hEditorWnd
, EM_SETEVENTMASK
, 0, ENM_SELCHANGE
);
1135 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
1137 ID_FINDMSGSTRING
= RegisterWindowMessageW(FINDMSGSTRINGW
);
1139 registry_read_filelist(hWnd
);
1144 static LRESULT
OnUser( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1146 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1147 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
1148 HWND hwndToolBar
= GetDlgItem(hwndReBar
, IDC_TOOLBAR
);
1149 HWND hwndFormatBar
= GetDlgItem(hwndReBar
, IDC_FORMATBAR
);
1155 ZeroMemory(&fmt
, sizeof(fmt
));
1156 fmt
.cbSize
= sizeof(fmt
);
1158 ZeroMemory(&pf
, sizeof(pf
));
1159 pf
.cbSize
= sizeof(pf
);
1161 gt
.flags
= GTL_NUMCHARS
;
1164 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_FIND
,
1165 SendMessageW(hwndEditor
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0) ? 1 : 0);
1167 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, TRUE
, (LPARAM
)&fmt
);
1169 SendMessageW(hwndEditor
, EM_GETSEL
, (WPARAM
)&from
, (LPARAM
)&to
);
1170 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_UNDO
,
1171 SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0));
1172 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_REDO
,
1173 SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0));
1174 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_CUT
, from
== to
? 0 : 1);
1175 SendMessageW(hwndToolBar
, TB_ENABLEBUTTON
, ID_EDIT_COPY
, from
== to
? 0 : 1);
1177 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_BOLD
, (fmt
.dwMask
& CFM_BOLD
) &&
1178 (fmt
.dwEffects
& CFE_BOLD
));
1179 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_BOLD
, !(fmt
.dwMask
& CFM_BOLD
));
1180 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_ITALIC
, (fmt
.dwMask
& CFM_ITALIC
) &&
1181 (fmt
.dwEffects
& CFE_ITALIC
));
1182 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_ITALIC
, !(fmt
.dwMask
& CFM_ITALIC
));
1183 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_FORMAT_UNDERLINE
, (fmt
.dwMask
& CFM_UNDERLINE
) &&
1184 (fmt
.dwEffects
& CFE_UNDERLINE
));
1185 SendMessageW(hwndFormatBar
, TB_INDETERMINATE
, ID_FORMAT_UNDERLINE
, !(fmt
.dwMask
& CFM_UNDERLINE
));
1187 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1188 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_LEFT
, (pf
.wAlignment
== PFA_LEFT
));
1189 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_CENTER
, (pf
.wAlignment
== PFA_CENTER
));
1190 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_ALIGN_RIGHT
, (pf
.wAlignment
== PFA_RIGHT
));
1192 SendMessageW(hwndFormatBar
, TB_CHECKBUTTON
, ID_BULLET
, (pf
.wNumbering
& PFN_BULLET
));
1196 static LRESULT
OnNotify( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1198 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1199 NMHDR
*pHdr
= (NMHDR
*)lParam
;
1201 if (pHdr
->hwndFrom
!= hwndEditor
)
1204 if (pHdr
->code
== EN_SELCHANGE
)
1206 SELCHANGE
*pSC
= (SELCHANGE
*)lParam
;
1209 sprintf( buf
,"selection = %d..%d, line count=%ld",
1210 pSC
->chrg
.cpMin
, pSC
->chrg
.cpMax
,
1211 SendMessage(hwndEditor
, EM_GETLINECOUNT
, 0, 0));
1212 SetWindowText(GetDlgItem(hWnd
, IDC_STATUSBAR
), buf
);
1213 SendMessage(hWnd
, WM_USER
, 0, 0);
1219 static LRESULT
OnCommand( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1221 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1222 HWND hwndStatus
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
1223 static FINDREPLACEW findreplace
;
1225 if ((HWND
)lParam
== hwndEditor
)
1228 switch(LOWORD(wParam
))
1232 PostMessageW(hWnd
, WM_CLOSE
, 0, 0);
1237 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1238 int ret
= DialogBox(hInstance
, MAKEINTRESOURCE(IDD_NEWFILE
), hWnd
,
1239 (DLGPROC
)newfile_proc
);
1241 if(ret
!= ID_NEWFILE_ABORT
)
1243 if(prompt_save_changes())
1248 wszFileName
[0] = '\0';
1250 st
.flags
= ST_DEFAULT
;
1252 SendMessageW(hEditorWnd
, EM_SETTEXTEX
, (WPARAM
)&st
, 0);
1256 SendMessageW(hEditorWnd
, EM_SETMODIFY
, FALSE
, 0);
1257 set_fileformat(ret
);
1270 DoSaveFile(wszFileName
, fileFormat
);
1275 case ID_FILE_SAVEAS
:
1279 case ID_FILE_RECENT1
:
1280 case ID_FILE_RECENT2
:
1281 case ID_FILE_RECENT3
:
1282 case ID_FILE_RECENT4
:
1284 HMENU hMenu
= GetMenu(hWnd
);
1287 mi
.cbSize
= sizeof(MENUITEMINFOW
);
1288 mi
.fMask
= MIIM_DATA
;
1289 if(GetMenuItemInfoW(hMenu
, LOWORD(wParam
), FALSE
, &mi
))
1290 DoOpenFile((LPWSTR
)mi
.dwItemData
);
1295 dialog_find(&findreplace
);
1299 handle_findmsg(&findreplace
);
1305 static const WCHAR wszNotImplemented
[] = {'N','o','t',' ',
1306 'i','m','p','l','e','m','e','n','t','e','d','\0'};
1307 MessageBoxW(hWnd
, wszNotImplemented
, wszAppTitle
, MB_OK
);
1311 case ID_FORMAT_BOLD
:
1312 case ID_FORMAT_ITALIC
:
1313 case ID_FORMAT_UNDERLINE
:
1316 int mask
= CFM_BOLD
;
1317 if (LOWORD(wParam
) == ID_FORMAT_ITALIC
) mask
= CFM_ITALIC
;
1318 if (LOWORD(wParam
) == ID_FORMAT_UNDERLINE
) mask
= CFM_UNDERLINE
;
1320 ZeroMemory(&fmt
, sizeof(fmt
));
1321 fmt
.cbSize
= sizeof(fmt
);
1322 SendMessageW(hwndEditor
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
1323 if (!(fmt
.dwMask
&mask
))
1324 fmt
.dwEffects
|= mask
;
1326 fmt
.dwEffects
^= mask
;
1328 SendMessageW(hwndEditor
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&fmt
);
1333 PostMessageW(hwndEditor
, WM_CUT
, 0, 0);
1337 PostMessageW(hwndEditor
, WM_COPY
, 0, 0);
1341 PostMessageW(hwndEditor
, WM_PASTE
, 0, 0);
1345 PostMessageW(hwndEditor
, WM_CLEAR
, 0, 0);
1348 case ID_EDIT_SELECTALL
:
1350 CHARRANGE range
= {0, -1};
1351 SendMessageW(hwndEditor
, EM_EXSETSEL
, 0, (LPARAM
)&range
);
1352 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
1356 case ID_EDIT_GETTEXT
:
1358 int nLen
= GetWindowTextLengthW(hwndEditor
);
1359 LPWSTR data
= HeapAlloc( GetProcessHeap(), 0, (nLen
+1)*sizeof(WCHAR
) );
1362 GetWindowTextW(hwndEditor
, data
, nLen
+1);
1363 MessageBoxW(NULL
, data
, xszAppTitle
, MB_OK
);
1365 HeapFree( GetProcessHeap(), 0, data
);
1366 data
= HeapAlloc(GetProcessHeap(), 0, (nLen
+1)*sizeof(WCHAR
));
1368 tr
.chrg
.cpMax
= nLen
;
1369 tr
.lpstrText
= data
;
1370 SendMessage (hwndEditor
, EM_GETTEXTRANGE
, 0, (LPARAM
)&tr
);
1371 MessageBoxW(NULL
, data
, xszAppTitle
, MB_OK
);
1372 HeapFree( GetProcessHeap(), 0, data
);
1374 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
1378 case ID_EDIT_CHARFORMAT
:
1379 case ID_EDIT_DEFCHARFORMAT
:
1383 ZeroMemory(&cf
, sizeof(cf
));
1384 cf
.cbSize
= sizeof(cf
);
1386 i
= SendMessageW(hwndEditor
, EM_GETCHARFORMAT
,
1387 LOWORD(wParam
) == ID_EDIT_CHARFORMAT
, (LPARAM
)&cf
);
1391 case ID_EDIT_PARAFORMAT
:
1394 ZeroMemory(&pf
, sizeof(pf
));
1395 pf
.cbSize
= sizeof(pf
);
1396 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1400 case ID_EDIT_SELECTIONINFO
:
1402 CHARRANGE range
= {0, -1};
1406 SendMessage(hwndEditor
, EM_EXGETSEL
, 0, (LPARAM
)&range
);
1407 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
) * (range
.cpMax
-range
.cpMin
+1));
1408 SendMessage(hwndEditor
, EM_GETSELTEXT
, 0, (LPARAM
)data
);
1409 sprintf(buf
, "Start = %d, End = %d", range
.cpMin
, range
.cpMax
);
1410 MessageBoxA(hWnd
, buf
, "Editor", MB_OK
);
1411 MessageBoxW(hWnd
, data
, xszAppTitle
, MB_OK
);
1412 HeapFree( GetProcessHeap(), 0, data
);
1413 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
1417 case ID_EDIT_READONLY
:
1419 long nStyle
= GetWindowLong(hwndEditor
, GWL_STYLE
);
1420 if (nStyle
& ES_READONLY
)
1421 SendMessageW(hwndEditor
, EM_SETREADONLY
, 0, 0);
1423 SendMessageW(hwndEditor
, EM_SETREADONLY
, 1, 0);
1427 case ID_EDIT_MODIFIED
:
1428 if (SendMessageW(hwndEditor
, EM_GETMODIFY
, 0, 0))
1429 SendMessageW(hwndEditor
, EM_SETMODIFY
, 0, 0);
1431 SendMessageW(hwndEditor
, EM_SETMODIFY
, 1, 0);
1435 SendMessageW(hwndEditor
, EM_UNDO
, 0, 0);
1439 SendMessageW(hwndEditor
, EM_REDO
, 0, 0);
1446 pf
.cbSize
= sizeof(pf
);
1447 pf
.dwMask
= PFM_NUMBERING
;
1448 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1450 pf
.dwMask
|= PFM_OFFSET
;
1452 if(pf
.wNumbering
== PFN_BULLET
)
1458 pf
.wNumbering
= PFN_BULLET
;
1462 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1467 case ID_ALIGN_CENTER
:
1468 case ID_ALIGN_RIGHT
:
1472 pf
.cbSize
= sizeof(pf
);
1473 pf
.dwMask
= PFM_ALIGNMENT
;
1474 switch(LOWORD(wParam
)) {
1475 case ID_ALIGN_LEFT
: pf
.wAlignment
= PFA_LEFT
; break;
1476 case ID_ALIGN_CENTER
: pf
.wAlignment
= PFA_CENTER
; break;
1477 case ID_ALIGN_RIGHT
: pf
.wAlignment
= PFA_RIGHT
; break;
1479 SendMessageW(hwndEditor
, EM_SETPARAFORMAT
, 0, (LPARAM
)&pf
);
1484 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 1, 0);
1488 SendMessageW(hwndEditor
, EM_SETBKGNDCOLOR
, 0, RGB(255,255,192));
1491 case ID_TOGGLE_TOOLBAR
:
1492 toggle_toolbar(BANDID_TOOLBAR
);
1496 case ID_TOGGLE_FORMATBAR
:
1497 toggle_toolbar(BANDID_FORMATBAR
);
1501 case ID_TOGGLE_STATUSBAR
:
1502 ShowWindow(hwndStatus
, IsWindowVisible(hwndStatus
) ? SW_HIDE
: SW_SHOW
);
1508 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLongPtr(hWnd
, GWLP_HINSTANCE
);
1509 DialogBoxW(hInstance
, MAKEINTRESOURCEW(IDD_DATETIME
), hWnd
, (DLGPROC
)datetime_proc
);
1514 SendMessageW(hwndEditor
, WM_COMMAND
, wParam
, lParam
);
1520 static LRESULT
OnInitPopupMenu( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1522 HMENU hMenu
= (HMENU
)wParam
;
1523 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1524 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
1525 HWND hwndStatus
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
1527 int nAlignment
= -1;
1528 REBARBANDINFOW rbbinfo
;
1534 SendMessageW(hEditorWnd
, EM_GETSEL
, (WPARAM
)&selFrom
, (LPARAM
)&selTo
);
1535 EnableMenuItem(hMenu
, ID_EDIT_COPY
, MF_BYCOMMAND
|(selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
1536 EnableMenuItem(hMenu
, ID_EDIT_CUT
, MF_BYCOMMAND
|(selFrom
== selTo
) ? MF_GRAYED
: MF_ENABLED
);
1538 pf
.cbSize
= sizeof(PARAFORMAT
);
1539 SendMessageW(hwndEditor
, EM_GETPARAFORMAT
, 0, (LPARAM
)&pf
);
1540 CheckMenuItem(hMenu
, ID_EDIT_READONLY
,
1541 MF_BYCOMMAND
|(GetWindowLong(hwndEditor
, GWL_STYLE
)&ES_READONLY
? MF_CHECKED
: MF_UNCHECKED
));
1542 CheckMenuItem(hMenu
, ID_EDIT_MODIFIED
,
1543 MF_BYCOMMAND
|(SendMessage(hwndEditor
, EM_GETMODIFY
, 0, 0) ? MF_CHECKED
: MF_UNCHECKED
));
1544 if (pf
.dwMask
& PFM_ALIGNMENT
)
1545 nAlignment
= pf
.wAlignment
;
1546 CheckMenuItem(hMenu
, ID_ALIGN_LEFT
, MF_BYCOMMAND
|(nAlignment
== PFA_LEFT
) ?
1547 MF_CHECKED
: MF_UNCHECKED
);
1548 CheckMenuItem(hMenu
, ID_ALIGN_CENTER
, MF_BYCOMMAND
|(nAlignment
== PFA_CENTER
) ?
1549 MF_CHECKED
: MF_UNCHECKED
);
1550 CheckMenuItem(hMenu
, ID_ALIGN_RIGHT
, MF_BYCOMMAND
|(nAlignment
== PFA_RIGHT
) ?
1551 MF_CHECKED
: MF_UNCHECKED
);
1552 CheckMenuItem(hMenu
, ID_BULLET
, MF_BYCOMMAND
| ((pf
.wNumbering
== PFN_BULLET
) ?
1553 MF_CHECKED
: MF_UNCHECKED
));
1554 EnableMenuItem(hMenu
, ID_EDIT_UNDO
, MF_BYCOMMAND
|(SendMessageW(hwndEditor
, EM_CANUNDO
, 0, 0)) ?
1555 MF_ENABLED
: MF_GRAYED
);
1556 EnableMenuItem(hMenu
, ID_EDIT_REDO
, MF_BYCOMMAND
|(SendMessageW(hwndEditor
, EM_CANREDO
, 0, 0)) ?
1557 MF_ENABLED
: MF_GRAYED
);
1559 rbbinfo
.cbSize
= sizeof(rbbinfo
);
1560 rbbinfo
.fMask
= RBBIM_STYLE
;
1561 SendMessageW(hwndReBar
, RB_GETBANDINFO
, BANDID_TOOLBAR
, (LPARAM
)&rbbinfo
);
1563 CheckMenuItem(hMenu
, ID_TOGGLE_TOOLBAR
, MF_BYCOMMAND
|(rbbinfo
.fStyle
& RBBS_HIDDEN
) ?
1564 MF_UNCHECKED
: MF_CHECKED
);
1566 SendMessageW(hwndReBar
, RB_GETBANDINFO
, BANDID_FORMATBAR
, (LPARAM
)&rbbinfo
);
1568 CheckMenuItem(hMenu
, ID_TOGGLE_FORMATBAR
, MF_BYCOMMAND
|(rbbinfo
.fStyle
& RBBS_HIDDEN
) ?
1569 MF_UNCHECKED
: MF_CHECKED
);
1571 CheckMenuItem(hMenu
, ID_TOGGLE_STATUSBAR
, MF_BYCOMMAND
|IsWindowVisible(hwndStatus
) ?
1572 MF_CHECKED
: MF_UNCHECKED
);
1574 gt
.flags
= GTL_NUMCHARS
;
1576 textLength
= SendMessageW(hEditorWnd
, EM_GETTEXTLENGTHEX
, (WPARAM
)>
, 0);
1577 EnableMenuItem(hMenu
, ID_FIND
, MF_BYCOMMAND
|(textLength
? MF_ENABLED
: MF_GRAYED
));
1579 mi
.cbSize
= sizeof(mi
);
1580 mi
.fMask
= MIIM_DATA
;
1582 GetMenuItemInfoW(hMenu
, ID_FIND_NEXT
, FALSE
, &mi
);
1584 EnableMenuItem(hMenu
, ID_FIND_NEXT
, MF_BYCOMMAND
|((textLength
&& mi
.dwItemData
) ?
1585 MF_ENABLED
: MF_GRAYED
));
1589 static LRESULT
OnSize( HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1591 int nStatusSize
= 0;
1593 HWND hwndEditor
= GetDlgItem(hWnd
, IDC_EDITOR
);
1594 HWND hwndStatusBar
= GetDlgItem(hWnd
, IDC_STATUSBAR
);
1595 HWND hwndReBar
= GetDlgItem(hWnd
, IDC_REBAR
);
1596 int rebarHeight
= 0;
1597 REBARBANDINFOW rbbinfo
;
1602 SendMessageW(hwndStatusBar
, WM_SIZE
, 0, 0);
1603 if (IsWindowVisible(hwndStatusBar
))
1605 GetClientRect(hwndStatusBar
, &rc
);
1606 nStatusSize
= rc
.bottom
- rc
.top
;
1614 rbbinfo
.cbSize
= sizeof(rbbinfo
);
1615 rbbinfo
.fMask
= RBBIM_STYLE
;
1617 SendMessageW(hwndReBar
, RB_GETBANDINFO
, BANDID_TOOLBAR
, (LPARAM
)&rbbinfo
);
1618 if(rbbinfo
.fStyle
& RBBS_HIDDEN
)
1621 SendMessageW(hwndReBar
, RB_GETBANDINFO
, BANDID_FORMATBAR
, (LPARAM
)&rbbinfo
);
1622 if(rbbinfo
.fStyle
& RBBS_HIDDEN
)
1625 rebarHeight
= rebarRows
? SendMessageW(hwndReBar
, RB_GETBARHEIGHT
, 0, 0) : 0;
1627 rc
.top
= rc
.left
= 0;
1628 rc
.bottom
= rebarHeight
;
1629 rc
.right
= LOWORD(lParam
);
1630 SendMessageW(hwndReBar
, RB_SIZETORECT
, 0, (LPARAM
)&rc
);
1634 GetClientRect(hWnd
, &rc
);
1635 MoveWindow(hwndEditor
, 0, rebarHeight
, rc
.right
, rc
.bottom
-nStatusSize
-rebarHeight
, TRUE
);
1638 return DefWindowProcW(hWnd
, WM_SIZE
, wParam
, lParam
);
1641 static LRESULT CALLBACK
WndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1643 if(msg
== ID_FINDMSGSTRING
)
1644 return handle_findmsg((LPFINDREPLACEW
)lParam
);
1649 return OnCreate( hWnd
, wParam
, lParam
);
1652 return OnUser( hWnd
, wParam
, lParam
);
1655 return OnNotify( hWnd
, wParam
, lParam
);
1658 return OnCommand( hWnd
, wParam
, lParam
);
1665 if(prompt_save_changes())
1667 registry_set_winrect();
1674 SetFocus(GetDlgItem(hWnd
, IDC_EDITOR
));
1677 case WM_INITMENUPOPUP
:
1678 return OnInitPopupMenu( hWnd
, wParam
, lParam
);
1681 return OnSize( hWnd
, wParam
, lParam
);
1684 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
1690 int CALLBACK
WinMain(HINSTANCE hInstance
, HINSTANCE hOldInstance
, LPSTR szCmdParagraph
, int res
)
1692 INITCOMMONCONTROLSEX classes
= {8, ICC_BAR_CLASSES
|ICC_COOL_CLASSES
};
1697 static const WCHAR wszAccelTable
[] = {'M','A','I','N','A','C','C','E','L',
1698 'T','A','B','L','E','\0'};
1700 InitCommonControlsEx(&classes
);
1702 hAccel
= LoadAcceleratorsW(hInstance
, wszAccelTable
);
1704 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1705 wc
.lpfnWndProc
= WndProc
;
1708 wc
.hInstance
= hInstance
;
1709 wc
.hIcon
= LoadIconW(hInstance
, MAKEINTRESOURCEW(IDI_WORDPAD
));
1710 wc
.hCursor
= LoadCursor(NULL
, IDC_IBEAM
);
1711 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
1712 wc
.lpszMenuName
= xszMainMenu
;
1713 wc
.lpszClassName
= wszMainWndClass
;
1714 RegisterClassW(&wc
);
1716 rc
= registry_read_winrect();
1717 hMainWnd
= CreateWindowExW(0, wszMainWndClass
, wszAppTitle
, WS_OVERLAPPEDWINDOW
,
1718 rc
.left
, rc
.top
, rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, NULL
, NULL
, hInstance
, NULL
);
1719 ShowWindow(hMainWnd
, SW_SHOWDEFAULT
);
1723 HandleCommandLine(GetCommandLineW());
1725 while(GetMessageW(&msg
,0,0,0))
1727 if (IsDialogMessage(hFindWnd
, &msg
))
1730 if (TranslateAcceleratorW(hMainWnd
, hAccel
, &msg
))
1732 TranslateMessage(&msg
);
1733 DispatchMessageW(&msg
);
1734 if (!PeekMessageW(&msg
, 0, 0, 0, PM_NOREMOVE
))
1735 SendMessageW(hMainWnd
, WM_USER
, 0, 0);