2 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
7 * Permission is hereby granted to use or copy this program
8 * for any purpose, provided the above notices are retained on all copies.
9 * Permission to modify the code and to distribute modified code is granted,
10 * provided the above notices are retained, and a notice that the code was
11 * modified is included with the above copyright notice.
15 * The MS Windows specific part of de.
16 * This started as the generic Windows application template
17 * but significant parts didn't survive to the final version.
19 * This was written by a nonexpert windows programmer.
31 char szAppName
[] = "DE";
32 char FullAppName
[] = "Demonstration Editor";
36 void de_error(char *s
)
38 MessageBox( hwnd
, (LPSTR
) s
,
40 MB_ICONINFORMATION
| MB_OK
);
41 InvalidateRect(hwnd
, NULL
, TRUE
);
44 int APIENTRY
WinMain (HINSTANCE hInstance
, HINSTANCE hPrevInstance
,
45 LPSTR command_line
, int nCmdShow
)
51 # ifdef THREAD_LOCAL_ALLOC
52 GC_INIT(); /* Required if GC is built with THREAD_LOCAL_ALLOC */
53 /* Always safe, but this is used as a GC test. */
58 wndclass
.style
= CS_HREDRAW
| CS_VREDRAW
;
59 wndclass
.lpfnWndProc
= WndProc
;
60 wndclass
.cbClsExtra
= 0;
61 wndclass
.cbWndExtra
= DLGWINDOWEXTRA
;
62 wndclass
.hInstance
= hInstance
;
63 wndclass
.hIcon
= LoadIcon (hInstance
, szAppName
);
64 wndclass
.hCursor
= LoadCursor (NULL
, IDC_ARROW
);
65 wndclass
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
66 wndclass
.lpszMenuName
= "DE";
67 wndclass
.lpszClassName
= szAppName
;
69 if (RegisterClass (&wndclass
) == 0) {
72 sprintf(buf
, "RegisterClass: error code: 0x%X",
73 (unsigned)GetLastError());
79 /* Empirically, the command line does not include the command name ...
80 if (command_line != 0) {
81 while (isspace(*command_line)) command_line++;
82 while (*command_line != 0 && !isspace(*command_line)) command_line++;
83 while (isspace(*command_line)) command_line++;
86 if (command_line
== 0 || *command_line
== 0) {
87 de_error("File name argument required");
90 char *p
= command_line
;
92 while (*p
!= 0 && !isspace(*p
)) p
++;
93 arg_file_name
= CORD_to_char_star(
94 CORD_substr(command_line
, 0, p
- command_line
));
97 hwnd
= CreateWindow (szAppName
,
99 WS_OVERLAPPEDWINDOW
| WS_CAPTION
, /* Window style */
100 CW_USEDEFAULT
, 0, /* default pos. */
101 CW_USEDEFAULT
, 0, /* default width, height */
102 NULL
, /* No parent */
103 NULL
, /* Window class menu */
108 sprintf(buf
, "CreateWindow: error code: 0x%X",
109 (unsigned)GetLastError());
114 ShowWindow (hwnd
, nCmdShow
);
116 hAccel
= LoadAccelerators( hInstance
, szAppName
);
118 while (GetMessage (&msg
, NULL
, 0, 0))
120 if( !TranslateAccelerator( hwnd
, hAccel
, &msg
) )
122 TranslateMessage (&msg
);
123 DispatchMessage (&msg
);
129 /* Return the argument with all control characters replaced by blanks. */
130 char * plain_chars(char * text
, size_t len
)
132 char * result
= GC_MALLOC_ATOMIC(len
+ 1);
135 for (i
= 0; i
< len
; i
++) {
136 if (iscntrl(text
[i
])) {
146 /* Return the argument with all non-control-characters replaced by */
147 /* blank, and all control characters c replaced by c + 32. */
148 char * control_chars(char * text
, size_t len
)
150 char * result
= GC_MALLOC_ATOMIC(len
+ 1);
153 for (i
= 0; i
< len
; i
++) {
154 if (iscntrl(text
[i
])) {
155 result
[i
] = text
[i
] + 0x40;
167 void get_line_rect(int line
, int win_width
, RECT
* rectp
)
169 rectp
-> top
= line
* char_height
;
170 rectp
-> bottom
= rectp
->top
+ char_height
;
172 rectp
-> right
= win_width
;
175 int caret_visible
= 0; /* Caret is currently visible. */
177 int screen_was_painted
= 0;/* Screen has been painted at least once. */
179 void update_cursor(void);
181 INT_PTR CALLBACK
AboutBoxCallback( HWND hDlg
, UINT message
,
182 WPARAM wParam
, LPARAM lParam
)
188 SetFocus( GetDlgItem( hDlg
, IDOK
) );
195 EndDialog( hDlg
, TRUE
);
201 EndDialog( hDlg
, TRUE
);
208 LRESULT CALLBACK
WndProc (HWND hwnd
, UINT message
,
209 WPARAM wParam
, LPARAM lParam
)
211 static HANDLE hInstance
;
224 hInstance
= ( (LPCREATESTRUCT
) lParam
)->hInstance
;
226 SelectObject(dc
, GetStockObject(SYSTEM_FIXED_FONT
));
227 GetTextMetrics(dc
, &tm
);
229 char_width
= tm
.tmAveCharWidth
;
230 char_height
= tm
.tmHeight
+ tm
.tmExternalLeading
;
231 GetClientRect(hwnd
, &client_area
);
232 COLS
= (client_area
.right
- client_area
.left
)/char_width
;
233 LINES
= (client_area
.bottom
- client_area
.top
)/char_height
;
238 if (wParam
== QUIT
) {
239 SendMessage( hwnd
, WM_CLOSE
, 0, 0L );
241 do_command((int)wParam
);
246 CreateCaret(hwnd
, NULL
, char_width
, char_height
);
260 unsigned xpos
= LOWORD(lParam
); /* From left */
261 unsigned ypos
= HIWORD(lParam
); /* from top */
263 set_position( xpos
/char_width
, ypos
/char_height
);
269 if (id
& EDIT_CMD_FLAG
) {
270 if (id
& REPEAT_FLAG
) do_command(REPEAT
);
271 do_command(CHAR_CMD(id
));
276 SendMessage( hwnd
, WM_CLOSE
, 0, 0L );
280 if( DialogBox( hInstance
, "ABOUTBOX",
281 hwnd
, AboutBoxCallback
) )
282 InvalidateRect( hwnd
, NULL
, TRUE
);
284 case IDM_HELPCONTENTS
:
286 "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
287 "Undo: ^U Write: ^W Quit:^D Repeat count: ^R[n]\n"
288 "Top: ^T Locate (search, find): ^L text ^L\n");
295 DestroyWindow( hwnd
);
300 GC_win32_free_heap();
304 dc
= BeginPaint(hwnd
, &ps
);
305 GetClientRect(hwnd
, &client_area
);
306 COLS
= (client_area
.right
- client_area
.left
)/char_width
;
307 LINES
= (client_area
.bottom
- client_area
.top
)/char_height
;
308 SelectObject(dc
, GetStockObject(SYSTEM_FIXED_FONT
));
309 for (i
= 0; i
< LINES
; i
++) {
310 get_line_rect(i
, client_area
.right
, &this_line
);
311 if (IntersectRect(&dummy
, &this_line
, &ps
.rcPaint
)) {
312 CORD raw_line
= retrieve_screen_line(i
);
313 size_t len
= CORD_len(raw_line
);
314 char * text
= CORD_to_char_star(raw_line
);
315 /* May contain embedded NULLs */
316 char * plain
= plain_chars(text
, len
);
317 char * blanks
= CORD_to_char_star(CORD_chars(' ',
319 char * control
= control_chars(text
, len
);
320 # define RED RGB(255,0,0)
322 SetBkMode(dc
, OPAQUE
);
323 SetTextColor(dc
, GetSysColor(COLOR_WINDOWTEXT
));
325 TextOut(dc
, this_line
.left
, this_line
.top
,
327 TextOut(dc
, this_line
.left
+ (int)len
* char_width
,
329 blanks
, (int)(COLS
- len
));
330 SetBkMode(dc
, TRANSPARENT
);
331 SetTextColor(dc
, RED
);
332 TextOut(dc
, this_line
.left
, this_line
.top
,
333 control
, (int)strlen(control
));
337 screen_was_painted
= 1;
340 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
346 void move_cursor(int c
, int l
)
351 if (caret_visible
) update_cursor();
354 void update_cursor(void)
356 SetCaretPos(last_col
* char_width
, last_line
* char_height
);
360 void invalidate_line(int i
)
364 if (!screen_was_painted
) return;
365 /* Invalidating a rectangle before painting seems result in a */
366 /* major performance problem. */
367 get_line_rect(i
, COLS
*char_width
, &line
);
368 InvalidateRect(hwnd
, &line
, FALSE
);