mshtml: Call update_doc in editor commands.
[wine/testsucceed.git] / programs / wordpad / wordpad.c
blob6efc15dc51454834705e335a85ef81dc42d9639c
1 /*
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
26 #include <stdarg.h>
27 #include <ctype.h>
28 #include <stdio.h>
29 #include <assert.h>
31 #include <windows.h>
32 #include <richedit.h>
33 #include <commctrl.h>
34 #include <commdlg.h>
36 #include "resource.h"
38 /* use LoadString */
39 static const WCHAR xszAppTitle[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
40 static const WCHAR xszMainMenu[] = {'M','A','I','N','M','E','N','U',0};
42 static const WCHAR wszRichEditClass[] = {'R','I','C','H','E','D','I','T','2','0','W',0};
43 static const WCHAR wszMainWndClass[] = {'W','O','R','D','P','A','D','T','O','P',0};
44 static const WCHAR wszAppTitle[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
46 static HWND hMainWnd;
47 static HWND hEditorWnd;
49 static WCHAR wszFilter[MAX_STRING_LEN];
51 /* Load string resources */
52 static void DoLoadStrings(void)
54 LPWSTR p = wszFilter;
55 static const WCHAR files_rtf[] = {'*','.','r','t','f','\0'};
56 static const WCHAR files_txt[] = {'*','.','t','x','t','\0'};
57 static const WCHAR files_all[] = {'*','.','*','\0'};
58 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hMainWnd, GWLP_HINSTANCE);
60 LoadStringW(hInstance, STRING_RICHTEXT_FILES_RTF, p, MAX_STRING_LEN);
61 p += lstrlenW(p) + 1;
62 lstrcpyW(p, files_rtf);
63 p += lstrlenW(p) + 1;
64 LoadStringW(hInstance, STRING_TEXT_FILES_TXT, p, MAX_STRING_LEN);
65 p += lstrlenW(p) + 1;
66 lstrcpyW(p, files_txt);
67 p += lstrlenW(p) + 1;
68 LoadStringW(hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN);
69 p += lstrlenW(p) + 1;
70 lstrcpyW(p, files_all);
71 p += lstrlenW(p) + 1;
72 *p = '\0';
75 static void AddButton(HWND hwndToolBar, int nImage, int nCommand)
77 TBBUTTON button;
79 ZeroMemory(&button, sizeof(button));
80 button.iBitmap = nImage;
81 button.idCommand = nCommand;
82 button.fsState = TBSTATE_ENABLED;
83 button.fsStyle = TBSTYLE_BUTTON;
84 button.dwData = 0;
85 button.iString = -1;
86 SendMessage(hwndToolBar, TB_ADDBUTTONS, 1, (LPARAM)&button);
89 static void AddSeparator(HWND hwndToolBar)
91 TBBUTTON button;
93 ZeroMemory(&button, sizeof(button));
94 button.iBitmap = -1;
95 button.idCommand = 0;
96 button.fsState = 0;
97 button.fsStyle = TBSTYLE_SEP;
98 button.dwData = 0;
99 button.iString = -1;
100 SendMessage(hwndToolBar, TB_ADDBUTTONS, 1, (LPARAM)&button);
103 static DWORD CALLBACK stream_in(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb)
105 HANDLE hFile = (HANDLE)cookie;
106 DWORD read;
108 if(!ReadFile(hFile, buffer, cb, &read, 0))
109 return 1;
111 *pcb = read;
113 return 0;
116 static DWORD CALLBACK stream_out(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb)
118 DWORD written;
119 int ret;
120 HANDLE hFile = (HANDLE)cookie;
122 ret = WriteFile(hFile, buffer, cb, &written, 0);
124 if(!ret || (cb != written))
125 return 1;
127 *pcb = cb;
129 return 0;
132 static WCHAR wszFileName[MAX_PATH];
134 static void set_caption(LPCWSTR wszNewFileName)
136 static const WCHAR wszSeparator[] = {' ','-',' '};
138 if(wszNewFileName)
140 WCHAR *wszCaption;
141 SIZE_T length = 0;
143 wszCaption = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
144 lstrlenW(wszNewFileName)*sizeof(WCHAR)+sizeof(wszSeparator)+sizeof(wszAppTitle));
146 if(!wszCaption)
147 return;
149 memcpy(wszCaption, wszNewFileName, lstrlenW(wszNewFileName)*sizeof(WCHAR));
150 length += lstrlenW(wszNewFileName);
151 memcpy(wszCaption + length, wszSeparator, sizeof(wszSeparator));
152 length += sizeof(wszSeparator) / sizeof(WCHAR);
153 memcpy(wszCaption + length, wszAppTitle, sizeof(wszAppTitle));
155 SetWindowTextW(hMainWnd, wszCaption);
157 HeapFree(GetProcessHeap(), 0, wszCaption);
158 } else
160 SetWindowTextW(hMainWnd, wszAppTitle);
164 static void DoOpenFile(LPCWSTR szOpenFileName)
166 HANDLE hFile;
167 EDITSTREAM es;
169 hFile = CreateFileW(szOpenFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
170 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
171 if (hFile == INVALID_HANDLE_VALUE)
172 return;
174 es.dwCookie = (DWORD_PTR)hFile;
175 es.pfnCallback = stream_in;
177 /* FIXME: Handle different file formats */
178 SendMessageW(hEditorWnd, EM_STREAMIN, SF_RTF, (LPARAM)&es);
180 CloseHandle(hFile);
182 SetFocus(hEditorWnd);
184 set_caption(szOpenFileName);
186 lstrcpyW(wszFileName, szOpenFileName);
189 static void DialogOpenFile(void)
191 OPENFILENAMEW ofn;
193 WCHAR wszFile[MAX_PATH] = {'\0'};
194 static const WCHAR wszDefExt[] = {'r','t','f','\0'};
196 ZeroMemory(&ofn, sizeof(ofn));
198 ofn.lStructSize = sizeof(ofn);
199 ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
200 ofn.hwndOwner = hMainWnd;
201 ofn.lpstrFilter = wszFilter;
202 ofn.lpstrFile = wszFile;
203 ofn.nMaxFile = MAX_PATH;
204 ofn.lpstrDefExt = wszDefExt;
206 if(GetOpenFileNameW(&ofn))
207 DoOpenFile(ofn.lpstrFile);
210 static void DoSaveFile(LPCWSTR wszSaveFileName)
212 HANDLE hFile;
213 EDITSTREAM stream;
214 LRESULT ret;
216 hFile = CreateFileW(wszSaveFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
217 FILE_ATTRIBUTE_NORMAL, NULL);
219 if(hFile == INVALID_HANDLE_VALUE)
220 return;
222 stream.dwCookie = (DWORD_PTR)hFile;
223 stream.pfnCallback = stream_out;
225 /* FIXME: Handle different formats */
226 ret = SendMessageW(hEditorWnd, EM_STREAMOUT, SF_RTF, (LPARAM)&stream);
228 CloseHandle(hFile);
230 SetFocus(hEditorWnd);
232 if(!ret)
233 return;
235 lstrcpyW(wszFileName, wszSaveFileName);
236 set_caption(wszFileName);
239 static void DialogSaveFile(void)
241 OPENFILENAMEW sfn;
243 WCHAR wszFile[MAX_PATH] = {'\0'};
244 static const WCHAR wszDefExt[] = {'r','t','f','\0'};
246 ZeroMemory(&sfn, sizeof(sfn));
248 sfn.lStructSize = sizeof(sfn);
249 sfn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
250 sfn.hwndOwner = hMainWnd;
251 sfn.lpstrFilter = wszFilter;
252 sfn.lpstrFile = wszFile;
253 sfn.nMaxFile = MAX_PATH;
254 sfn.lpstrDefExt = wszDefExt;
256 if(!GetSaveFileNameW(&sfn))
257 return;
259 DoSaveFile(sfn.lpstrFile);
262 static void HandleCommandLine(LPWSTR cmdline)
264 WCHAR delimiter;
265 int opt_print = 0;
267 /* skip white space */
268 while (*cmdline == ' ') cmdline++;
270 /* skip executable name */
271 delimiter = (*cmdline == '"' ? '"' : ' ');
273 if (*cmdline == delimiter) cmdline++;
274 while (*cmdline && *cmdline != delimiter) cmdline++;
275 if (*cmdline == delimiter) cmdline++;
277 while (*cmdline == ' ' || *cmdline == '-' || *cmdline == '/')
279 WCHAR option;
281 if (*cmdline++ == ' ') continue;
283 option = *cmdline;
284 if (option) cmdline++;
285 while (*cmdline == ' ') cmdline++;
287 switch (option)
289 case 'p':
290 case 'P':
291 opt_print = 1;
292 break;
296 if (*cmdline)
298 /* file name is passed on the command line */
299 if (cmdline[0] == '"')
301 cmdline++;
302 cmdline[lstrlenW(cmdline) - 1] = 0;
304 DoOpenFile(cmdline);
305 InvalidateRect(hMainWnd, NULL, FALSE);
308 if (opt_print)
309 MessageBox(hMainWnd, "Printing not implemented", "WordPad", MB_OK);
312 static void DoDefaultFont(void)
314 static const WCHAR szFaceName[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0};
315 CHARFORMAT2W fmt;
317 ZeroMemory(&fmt, sizeof(fmt));
319 fmt.cbSize = sizeof(fmt);
320 fmt.dwMask = CFM_FACE;
322 lstrcpyW(fmt.szFaceName, szFaceName);
324 SendMessage(hEditorWnd, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&fmt);
327 static LRESULT OnCreate( HWND hWnd, WPARAM wParam, LPARAM lParam)
329 HWND hToolBarWnd, hReBarWnd;
330 HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
331 HANDLE hDLL;
332 TBADDBITMAP ab;
333 int nStdBitmaps = 0;
334 REBARINFO rbi;
335 REBARBANDINFO rbb;
337 CreateStatusWindow(CCS_NODIVIDER|WS_CHILD|WS_VISIBLE, "RichEdit text", hWnd, IDC_STATUSBAR);
339 hReBarWnd = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
340 CCS_NODIVIDER|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|RBS_VARHEIGHT|CCS_TOP,
341 CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hWnd, (HMENU)IDC_REBAR, hInstance, NULL);
343 rbi.cbSize = sizeof(rbi);
344 rbi.fMask = 0;
345 rbi.himl = NULL;
346 if(!SendMessage(hReBarWnd, RB_SETBARINFO, 0, (LPARAM)&rbi))
347 return -1;
349 hToolBarWnd = CreateToolbarEx(hReBarWnd, CCS_NOPARENTALIGN|CCS_NOMOVEY|WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS|TBSTYLE_BUTTON,
350 IDC_TOOLBAR,
351 6, hInstance, IDB_TOOLBAR,
352 NULL, 0,
353 24, 24, 16, 16, sizeof(TBBUTTON));
355 ab.hInst = HINST_COMMCTRL;
356 ab.nID = IDB_STD_SMALL_COLOR;
357 nStdBitmaps = SendMessage(hToolBarWnd, TB_ADDBITMAP, 6, (LPARAM)&ab);
358 AddButton(hToolBarWnd, nStdBitmaps+STD_FILENEW, ID_FILE_NEW);
359 AddButton(hToolBarWnd, nStdBitmaps+STD_FILEOPEN, ID_FILE_OPEN);
360 AddButton(hToolBarWnd, nStdBitmaps+STD_FILESAVE, ID_FILE_SAVE);
361 AddSeparator(hToolBarWnd);
362 AddButton(hToolBarWnd, nStdBitmaps+STD_PRINT, ID_PRINT);
363 AddButton(hToolBarWnd, nStdBitmaps+STD_PRINTPRE, ID_PREVIEW);
364 AddSeparator(hToolBarWnd);
365 AddButton(hToolBarWnd, nStdBitmaps+STD_FIND, ID_FIND);
366 AddSeparator(hToolBarWnd);
367 AddButton(hToolBarWnd, nStdBitmaps+STD_CUT, ID_EDIT_CUT);
368 AddButton(hToolBarWnd, nStdBitmaps+STD_COPY, ID_EDIT_COPY);
369 AddButton(hToolBarWnd, nStdBitmaps+STD_PASTE, ID_EDIT_PASTE);
370 AddButton(hToolBarWnd, nStdBitmaps+STD_UNDO, ID_EDIT_UNDO);
371 AddButton(hToolBarWnd, nStdBitmaps+STD_REDOW, ID_EDIT_REDO);
372 AddSeparator(hToolBarWnd);
373 AddButton(hToolBarWnd, 0, ID_FORMAT_BOLD);
374 AddButton(hToolBarWnd, 1, ID_FORMAT_ITALIC);
375 AddButton(hToolBarWnd, 2, ID_FORMAT_UNDERLINE);
376 AddSeparator(hToolBarWnd);
377 AddButton(hToolBarWnd, 3, ID_ALIGN_LEFT);
378 AddButton(hToolBarWnd, 4, ID_ALIGN_CENTER);
379 AddButton(hToolBarWnd, 5, ID_ALIGN_RIGHT);
381 SendMessage(hToolBarWnd, TB_ADDSTRING, 0, (LPARAM)"Exit\0");
382 SendMessage(hToolBarWnd, TB_AUTOSIZE, 0, 0);
384 rbb.cbSize = sizeof(rbb);
385 rbb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_STYLE;
386 rbb.fStyle = RBBS_CHILDEDGE;
387 rbb.cx = 500;
388 rbb.hwndChild = hToolBarWnd;
389 rbb.cxMinChild = 0;
390 rbb.cyChild = rbb.cyMinChild = HIWORD(SendMessage(hToolBarWnd, TB_GETBUTTONSIZE, 0, 0));
392 SendMessage(hReBarWnd, RB_INSERTBAND, -1, (LPARAM)&rbb);
394 hDLL = LoadLibrary("RICHED20.DLL");
395 assert(hDLL);
397 hEditorWnd = CreateWindowExW(WS_EX_CLIENTEDGE, wszRichEditClass, NULL,
398 WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOVSCROLL|ES_WANTRETURN|WS_VSCROLL,
399 0, 0, 1000, 100, hWnd, (HMENU)IDC_EDITOR, hInstance, NULL);
400 if (!hEditorWnd)
402 fprintf(stderr, "Error code %u\n", GetLastError());
403 return -1;
405 assert(hEditorWnd);
407 SetFocus(hEditorWnd);
408 SendMessage(hEditorWnd, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
410 DoDefaultFont();
412 DoLoadStrings();
414 return 0;
417 static LRESULT OnUser( HWND hWnd, WPARAM wParam, LPARAM lParam)
419 HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
420 HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR);
421 HWND hwndToolBar = GetDlgItem(hwndReBar, IDC_TOOLBAR);
422 int from, to;
423 CHARFORMAT2W fmt;
424 PARAFORMAT2 pf;
426 ZeroMemory(&fmt, sizeof(fmt));
427 fmt.cbSize = sizeof(fmt);
429 ZeroMemory(&pf, sizeof(pf));
430 pf.cbSize = sizeof(pf);
432 SendMessage(hwndEditor, EM_GETCHARFORMAT, TRUE, (LPARAM)&fmt);
434 SendMessage(hwndEditor, EM_GETSEL, (WPARAM)&from, (LPARAM)&to);
435 SendMessage(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_UNDO,
436 SendMessage(hwndEditor, EM_CANUNDO, 0, 0));
437 SendMessage(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_REDO,
438 SendMessage(hwndEditor, EM_CANREDO, 0, 0));
439 SendMessage(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_CUT, from == to ? 0 : 1);
440 SendMessage(hwndToolBar, TB_ENABLEBUTTON, ID_EDIT_COPY, from == to ? 0 : 1);
441 SendMessage(hwndToolBar, TB_CHECKBUTTON, ID_FORMAT_BOLD, (fmt.dwMask & CFM_BOLD) && (fmt.dwEffects & CFE_BOLD));
442 SendMessage(hwndToolBar, TB_INDETERMINATE, ID_FORMAT_BOLD, !(fmt.dwMask & CFM_BOLD));
443 SendMessage(hwndToolBar, TB_CHECKBUTTON, ID_FORMAT_ITALIC, (fmt.dwMask & CFM_ITALIC) && (fmt.dwEffects & CFE_ITALIC));
444 SendMessage(hwndToolBar, TB_INDETERMINATE, ID_FORMAT_ITALIC, !(fmt.dwMask & CFM_ITALIC));
445 SendMessage(hwndToolBar, TB_CHECKBUTTON, ID_FORMAT_UNDERLINE, (fmt.dwMask & CFM_UNDERLINE) && (fmt.dwEffects & CFE_UNDERLINE));
446 SendMessage(hwndToolBar, TB_INDETERMINATE, ID_FORMAT_UNDERLINE, !(fmt.dwMask & CFM_UNDERLINE));
448 SendMessage(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
449 SendMessage(hwndToolBar, TB_CHECKBUTTON, ID_ALIGN_LEFT, (pf.wAlignment == PFA_LEFT));
450 SendMessage(hwndToolBar, TB_CHECKBUTTON, ID_ALIGN_CENTER, (pf.wAlignment == PFA_CENTER));
451 SendMessage(hwndToolBar, TB_CHECKBUTTON, ID_ALIGN_RIGHT, (pf.wAlignment == PFA_RIGHT));
453 return 0;
456 static LRESULT OnNotify( HWND hWnd, WPARAM wParam, LPARAM lParam)
458 HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
459 NMHDR *pHdr = (NMHDR *)lParam;
461 if (pHdr->hwndFrom != hwndEditor)
462 return 0;
464 if (pHdr->code == EN_SELCHANGE)
466 SELCHANGE *pSC = (SELCHANGE *)lParam;
467 char buf[128];
469 sprintf( buf,"selection = %d..%d, line count=%ld",
470 pSC->chrg.cpMin, pSC->chrg.cpMax,
471 SendMessage(hwndEditor, EM_GETLINECOUNT, 0, 0));
472 SetWindowText(GetDlgItem(hWnd, IDC_STATUSBAR), buf);
473 SendMessage(hWnd, WM_USER, 0, 0);
474 return 1;
476 return 0;
479 static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam)
481 HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
483 if ((HWND)lParam == hwndEditor)
484 return 0;
486 switch(LOWORD(wParam))
488 case ID_FILE_EXIT:
489 PostMessage(hWnd, WM_CLOSE, 0, 0);
490 break;
492 case ID_FILE_NEW:
493 SetWindowTextA(hwndEditor, "");
494 set_caption(NULL);
495 wszFileName[0] = '\0';
496 /* FIXME: set default format too */
497 break;
499 case ID_FILE_OPEN:
500 DialogOpenFile();
501 break;
503 case ID_FILE_SAVE:
504 if(wszFileName[0])
506 DoSaveFile(wszFileName);
507 break;
509 /* Fall through */
511 case ID_FILE_SAVEAS:
512 DialogSaveFile();
513 break;
515 case ID_PRINT:
516 case ID_PREVIEW:
517 case ID_FIND:
518 MessageBox(hWnd, "Not implemented", "WordPad", MB_OK);
519 break;
521 case ID_FORMAT_BOLD:
522 case ID_FORMAT_ITALIC:
523 case ID_FORMAT_UNDERLINE:
525 CHARFORMAT2W fmt;
526 int mask = CFM_BOLD;
527 if (LOWORD(wParam) == ID_FORMAT_ITALIC) mask = CFM_ITALIC;
528 if (LOWORD(wParam) == ID_FORMAT_UNDERLINE) mask = CFM_UNDERLINE;
530 ZeroMemory(&fmt, sizeof(fmt));
531 fmt.cbSize = sizeof(fmt);
532 SendMessage(hwndEditor, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
533 if (!(fmt.dwMask&mask))
534 fmt.dwEffects |= mask;
535 else
536 fmt.dwEffects ^= mask;
537 fmt.dwMask = mask;
538 SendMessage(hwndEditor, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
539 break;
542 case ID_EDIT_CUT:
543 PostMessage(hwndEditor, WM_CUT, 0, 0);
544 break;
546 case ID_EDIT_COPY:
547 PostMessage(hwndEditor, WM_COPY, 0, 0);
548 break;
550 case ID_EDIT_PASTE:
551 PostMessage(hwndEditor, WM_PASTE, 0, 0);
552 break;
554 case ID_EDIT_CLEAR:
555 PostMessage(hwndEditor, WM_CLEAR, 0, 0);
556 break;
558 case ID_EDIT_SELECTALL:
560 CHARRANGE range = {0, -1};
561 SendMessage(hwndEditor, EM_EXSETSEL, 0, (LPARAM)&range);
562 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
563 return 0;
566 case ID_EDIT_GETTEXT:
568 int nLen = GetWindowTextLengthW(hwndEditor);
569 LPWSTR data = HeapAlloc( GetProcessHeap(), 0, (nLen+1)*sizeof(WCHAR) );
570 TEXTRANGEW tr;
572 GetWindowTextW(hwndEditor, data, nLen+1);
573 MessageBoxW(NULL, data, xszAppTitle, MB_OK);
575 HeapFree( GetProcessHeap(), 0, data);
576 data = HeapAlloc(GetProcessHeap(), 0, (nLen+1)*sizeof(WCHAR));
577 tr.chrg.cpMin = 0;
578 tr.chrg.cpMax = nLen;
579 tr.lpstrText = data;
580 SendMessage (hwndEditor, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
581 MessageBoxW(NULL, data, xszAppTitle, MB_OK);
582 HeapFree( GetProcessHeap(), 0, data );
584 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
585 return 0;
588 case ID_EDIT_CHARFORMAT:
589 case ID_EDIT_DEFCHARFORMAT:
591 CHARFORMAT2W cf;
592 LRESULT i;
593 ZeroMemory(&cf, sizeof(cf));
594 cf.cbSize = sizeof(cf);
595 cf.dwMask = 0;
596 i = SendMessage(hwndEditor, EM_GETCHARFORMAT,
597 LOWORD(wParam) == ID_EDIT_CHARFORMAT, (LPARAM)&cf);
598 return 0;
601 case ID_EDIT_PARAFORMAT:
603 PARAFORMAT2 pf;
604 ZeroMemory(&pf, sizeof(pf));
605 pf.cbSize = sizeof(pf);
606 SendMessage(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
607 return 0;
610 case ID_EDIT_SELECTIONINFO:
612 CHARRANGE range = {0, -1};
613 char buf[128];
614 WCHAR *data = NULL;
616 SendMessage(hwndEditor, EM_EXGETSEL, 0, (LPARAM)&range);
617 data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * (range.cpMax-range.cpMin+1));
618 SendMessage(hwndEditor, EM_GETSELTEXT, 0, (LPARAM)data);
619 sprintf(buf, "Start = %d, End = %d", range.cpMin, range.cpMax);
620 MessageBoxA(hWnd, buf, "Editor", MB_OK);
621 MessageBoxW(hWnd, data, xszAppTitle, MB_OK);
622 HeapFree( GetProcessHeap(), 0, data);
623 /* SendMessage(hwndEditor, EM_SETSEL, 0, -1); */
624 return 0;
627 case ID_EDIT_READONLY:
629 long nStyle = GetWindowLong(hwndEditor, GWL_STYLE);
630 if (nStyle & ES_READONLY)
631 SendMessage(hwndEditor, EM_SETREADONLY, 0, 0);
632 else
633 SendMessage(hwndEditor, EM_SETREADONLY, 1, 0);
634 return 0;
637 case ID_EDIT_MODIFIED:
638 if (SendMessage(hwndEditor, EM_GETMODIFY, 0, 0))
639 SendMessage(hwndEditor, EM_SETMODIFY, 0, 0);
640 else
641 SendMessage(hwndEditor, EM_SETMODIFY, 1, 0);
642 return 0;
644 case ID_EDIT_UNDO:
645 SendMessage(hwndEditor, EM_UNDO, 0, 0);
646 return 0;
648 case ID_EDIT_REDO:
649 SendMessage(hwndEditor, EM_REDO, 0, 0);
650 return 0;
652 case ID_ALIGN_LEFT:
653 case ID_ALIGN_CENTER:
654 case ID_ALIGN_RIGHT:
656 PARAFORMAT2 pf;
658 pf.cbSize = sizeof(pf);
659 pf.dwMask = PFM_ALIGNMENT;
660 switch(LOWORD(wParam)) {
661 case ID_ALIGN_LEFT: pf.wAlignment = PFA_LEFT; break;
662 case ID_ALIGN_CENTER: pf.wAlignment = PFA_CENTER; break;
663 case ID_ALIGN_RIGHT: pf.wAlignment = PFA_RIGHT; break;
665 SendMessage(hwndEditor, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
666 break;
669 case ID_BACK_1:
670 SendMessage(hwndEditor, EM_SETBKGNDCOLOR, 1, 0);
671 break;
673 case ID_BACK_2:
674 SendMessage(hwndEditor, EM_SETBKGNDCOLOR, 0, RGB(255,255,192));
675 break;
677 default:
678 SendMessage(hwndEditor, WM_COMMAND, wParam, lParam);
679 break;
681 return 0;
684 static LRESULT OnInitPopupMenu( HWND hWnd, WPARAM wParam, LPARAM lParam )
686 HMENU hMenu = (HMENU)wParam;
687 HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
688 PARAFORMAT pf;
689 int nAlignment = -1;
691 pf.cbSize = sizeof(PARAFORMAT);
692 SendMessage(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf);
693 CheckMenuItem(hMenu, ID_EDIT_READONLY,
694 MF_BYCOMMAND|(GetWindowLong(hwndEditor, GWL_STYLE)&ES_READONLY ? MF_CHECKED : MF_UNCHECKED));
695 CheckMenuItem(hMenu, ID_EDIT_MODIFIED,
696 MF_BYCOMMAND|(SendMessage(hwndEditor, EM_GETMODIFY, 0, 0) ? MF_CHECKED : MF_UNCHECKED));
697 if (pf.dwMask & PFM_ALIGNMENT)
698 nAlignment = pf.wAlignment;
699 CheckMenuItem(hMenu, ID_ALIGN_LEFT, MF_BYCOMMAND|(nAlignment == PFA_LEFT) ? MF_CHECKED : MF_UNCHECKED);
700 CheckMenuItem(hMenu, ID_ALIGN_CENTER, MF_BYCOMMAND|(nAlignment == PFA_CENTER) ? MF_CHECKED : MF_UNCHECKED);
701 CheckMenuItem(hMenu, ID_ALIGN_RIGHT, MF_BYCOMMAND|(nAlignment == PFA_RIGHT) ? MF_CHECKED : MF_UNCHECKED);
702 EnableMenuItem(hMenu, ID_EDIT_UNDO, MF_BYCOMMAND|(SendMessage(hwndEditor, EM_CANUNDO, 0, 0)) ? MF_ENABLED : MF_GRAYED);
703 EnableMenuItem(hMenu, ID_EDIT_REDO, MF_BYCOMMAND|(SendMessage(hwndEditor, EM_CANREDO, 0, 0)) ? MF_ENABLED : MF_GRAYED);
704 return 0;
707 static LRESULT OnSize( HWND hWnd, WPARAM wParam, LPARAM lParam )
709 int nStatusSize = 0, nTBSize = 0;
710 RECT rc;
711 HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR);
712 HWND hwndStatusBar = GetDlgItem(hWnd, IDC_STATUSBAR);
713 HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR);
714 HWND hwndToolBar = GetDlgItem(hwndReBar, IDC_TOOLBAR);
716 if (hwndStatusBar)
718 SendMessage(hwndStatusBar, WM_SIZE, 0, 0);
719 GetClientRect(hwndStatusBar, &rc);
720 nStatusSize = rc.bottom - rc.top;
722 if (hwndToolBar)
724 rc.left = rc.top = 0;
725 rc.right = LOWORD(lParam);
726 rc.bottom = HIWORD(lParam);
727 SendMessage(hwndToolBar, TB_AUTOSIZE, 0, 0);
728 SendMessage(hwndReBar, RB_SIZETORECT, 0, (LPARAM)&rc);
729 nTBSize = SendMessage(hwndReBar, RB_GETBARHEIGHT, 0, 0);
730 GetClientRect(hwndReBar, &rc);
731 MoveWindow(hwndReBar, 0, 0, LOWORD(lParam), rc.right, FALSE);
733 if (hwndEditor)
735 GetClientRect(hWnd, &rc);
736 MoveWindow(hwndEditor, 0, nTBSize, rc.right, rc.bottom-nStatusSize-nTBSize, TRUE);
739 return DefWindowProcW(hWnd, WM_SIZE, wParam, lParam);
742 static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
744 switch(msg)
746 case WM_CREATE:
747 return OnCreate( hWnd, wParam, lParam );
749 case WM_USER:
750 return OnUser( hWnd, wParam, lParam );
752 case WM_NOTIFY:
753 return OnNotify( hWnd, wParam, lParam );
755 case WM_COMMAND:
756 return OnCommand( hWnd, wParam, lParam );
758 case WM_DESTROY:
759 PostQuitMessage(0);
760 break;
762 case WM_ACTIVATE:
763 if (LOWORD(wParam))
764 SetFocus(GetDlgItem(hWnd, IDC_EDITOR));
765 return 0;
767 case WM_INITMENUPOPUP:
768 return OnInitPopupMenu( hWnd, wParam, lParam );
770 case WM_SIZE:
771 return OnSize( hWnd, wParam, lParam );
773 default:
774 return DefWindowProcW(hWnd, msg, wParam, lParam);
777 return 0;
780 int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hOldInstance, LPSTR szCmdParagraph, int res)
782 INITCOMMONCONTROLSEX classes = {8, ICC_BAR_CLASSES|ICC_COOL_CLASSES};
783 HACCEL hAccel;
784 WNDCLASSW wc;
785 MSG msg;
787 InitCommonControlsEx(&classes);
789 hAccel = LoadAccelerators(hInstance, "MAINACCELTABLE");
791 wc.style = CS_HREDRAW | CS_VREDRAW;
792 wc.lpfnWndProc = WndProc;
793 wc.cbClsExtra = 0;
794 wc.cbWndExtra = 4;
795 wc.hInstance = hInstance;
796 wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_WORDPAD));
797 wc.hCursor = LoadCursor(NULL, IDC_IBEAM);
798 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
799 wc.lpszMenuName = xszMainMenu;
800 wc.lpszClassName = wszMainWndClass;
801 RegisterClassW(&wc);
803 hMainWnd = CreateWindowExW(0, wszMainWndClass, wszAppTitle, WS_OVERLAPPEDWINDOW,
804 CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, hInstance, NULL);
805 ShowWindow(hMainWnd, SW_SHOWDEFAULT);
807 HandleCommandLine(GetCommandLineW());
809 while(GetMessage(&msg,0,0,0))
811 if (TranslateAccelerator(hMainWnd, hAccel, &msg))
812 continue;
813 TranslateMessage(&msg);
814 DispatchMessage(&msg);
815 if (!PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
816 SendMessage(hMainWnd, WM_USER, 0, 0);
819 return 0;