source: trunk/src/netlabs/macros/stdctrl.e@ 4868

Last change on this file since 4868 was 4868, checked in by Andreas Schnellbacher, 3 years ago
  • Cosmetic changes.
  • Property svn:keywords set to Date Revision Author HeadURL Id
File size: 149.5 KB
Line 
1/****************************** Module Header *******************************
2*
3* Module Name: stdctrl.e
4*
5* Copyright (c) Netlabs EPM Distribution Project 2002
6*
7* $Id: stdctrl.e 4868 2022-01-17 08:50:27Z aschn $
8*
9* ===========================================================================
10*
11* This file is part of the Netlabs EPM Distribution package and is free
12* software. You can redistribute it and/or modify it under the terms of the
13* GNU General Public License as published by the Free Software
14* Foundation, in version 2 as it comes in the "COPYING" file of the
15* Netlabs EPM Distribution. This library is distributed in the hope that it
16* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18* General Public License for more details.
19*
20****************************************************************************/
21
22compile if not defined( SMALL) -- If compiled separately
23 EA_comment 'PM controls.'
24
25define
26 INCLUDING_FILE = 'STDCTRL.E'
27
28 include 'stdconst.e'
29const
30 tryinclude 'mycnf.e'
31const
32 compile if not defined( NLS_LANGUAGE)
33 NLS_LANGUAGE = 'ENGLISH'
34 compile endif
35 include NLS_LANGUAGE'.e'
36compile endif
37
38; ---------------------------------------------------------------------------
39/*
40ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
41º What's it called: stdctrl.e º
42º º
43º What does it do : contains special PM procedures and commands that enable º
44º the following from the EPM editor: º
45º º
46º listbox support - enables the dynamic creation of PM º
47º list boxes. A macro can pop up a º
48º list of items and have a the users º
49º selection returned to the macro. º
50º º
51º menu support - enables the dynamic creation and º
52º maintenance of named menus. º
53º A macro can create several menus that º
54º when shown and selected can execute º
55º editor commands. º
56º º
57º EPM - E.DLL communication : º
58º gives a EPM macro the ability to º
59º converse with EPM.EXE controls. º
60º For Example, popping EPM's commandline º
61º message dialog, etc. º
62º º
63º Who and When : Gennaro (Jerry) Cuomo 3 -88 º
64º º
65ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ
66*/
67
68/*
69ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
70³ List Box Functions: ³
71³ ³
72³ ListBox() ³
73³ listdemo() ³
74³ listdemo2() ³
75ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
76*/
77
78; ---------------------------------------------------------------------------
79; EPM bug of the ListBox proc, eventually only in conjunction with NewView:
80; On closing the list box dialog, a previously opened EPM.HLP via the Help
81; Manager is closed, too. It doesn't matter how the dialog is closed.
82; That doesn't happen for any other dialog nor if the .HLP file was opened
83; without the Help Manager.
84
85; ---------------------------------------------------------------------------
86; ListBox()
87; param1 - Listbox title
88;
89; param2 - string of items, separated by a common separator. The common
90; separator is the first character in the string.
91; example: /cat/dog/fish/
92; separator='/' list=cat, dog, fish
93; example: $cat/ground$fish/water$
94; separator='$' list=cat/ground, fish/water
95;
96; If this parameter starts with an x'00', then it will be assumed to
97; represent a buffer, in the format:
98;
99; \0 || atol(usedsize) || atoi(buffer_offset) || atoi(buffer_selector) [ || flag ]
100;
101; The default flag is 3. The bits are:
102; 1 - Display the listbox below the specified point.
103; 2 - Map the specified points to the desktop.
104; 4 - Each listbox item starts with an ASCII help panel ID.
105; The IDs are removed before filling the listbox. The
106; first button is assumed to be a Details button.
107; Pressing it invokes help for the panel ID associated
108; with the current listbox item. (This feature is used by
109; the Workframe/2.)
110; Other flags from older versions are not supported.
111;
112; The function listbox_buffer_from_file, defined in STDCTRL.E,
113; can be used for putting the contents of a file into a buffer
114; in a suitable format for listbox(). It requires an empty line
115; at the top, as created by 'xcom e /n'
116;
117; param3 - (optional) button names. A maximum of seven button names can be
118; specified to allow multiple buttons.
119;
120; param4 - (optional) row of text in which list box will go under.
121; If this parameter is not specified or if a parameter of zero (0)
122; is specified, the box will be placed centered.
123; If the parameter 'C' is used, the box will be placed beneath the
124; cursor.
125;
126; param5 - (optional) column of text in which list box will go under.
127; If this parameter is not specified or if a parameter of zero (0)
128; is specified, the box will be placed centered.
129; If the parameter 'C' is used, the box will be placed beneath the
130; cursor.
131; NOTE: If the row parameter is selected, the column parameter
132; must be selected as well.
133; NOTE: Previously, "beneath the cursor" was the default behavior.
134; That seems to behave annoying in most cases, therefore
135; that was changed to place the box centered. To place it
136; beneath the cursor, now 'C' has to be specified explicitely
137; for param4 and 5.
138;
139; param6 - (optional) height of the listbox in characters
140; (NOTE: Since the default PM font is proportional, the character
141; height and width are approximate values.)
142;
143; param7 - (optional) width of listbox in characters.
144;
145; param8 - (optional) buffer string (see below)
146;
147; The following procedure creates a PM list box dialog. The listbox will
148; wait for user input and return a value that corresponds to the users input.
149;
150; If the user presses Enter or double clicks on an entry, that entry will
151; be returned as the result of the listbox function.
152;
153; If Cancel is selected or Esc is pressed, the listbox function will return
154; null.
155;
156; The listbox is a modal listbox, therefore user input is required before
157; anything else can happen.
158;
159; Jerry Cuomo 1-89
160;
161; EPM 5.21 / 5.50 added some new features to the ETOOLKIT interface. Parameter
162; 8 is used to expose this to the caller of listbox().
163;
164; If present, it is a string consisting of:
165;
166; handle || item# || button# || help_ID || prompt
167;
168; where
169;
170; item# is the listbox entry to be initially selected,
171;
172; button# is the button that will be the default,
173;
174; help_ID is a help panel ID (all shorts),
175;
176; handle is the window handle of the OWNERCLIENT (needed to call help;
177; ignored if help_ID is 0) and
178; prompt is an ASCIIZ string to be displayed below the title bar. If
179; help_ID is non-zero, the rightmost button is assumed to be the
180; help button.
181;
182; The new parameters are passed to the toolkit in the return buffer, which is
183; padded with nulls, so only the minimum needed string need be sent.
184;
185; The new way returns one byte representing the button number (in hex)
186; followed by the selected item. A button number of 0 means Esc was pressed
187; or the dialog was closed.
188;
189; If param8 was passed, the listbox() routine returns this entire string; if
190; not, it parses it and returns what the old callers expected.
191;
192; Larry Margolis / John Ponzo 6/91
193;
194; ----
195;
196; Correction/clarification of FLAGS description of bits 0 and 1:
197; bit 0
198; 0: y = bottom of listbox
199; 1: y = top of listbox
200; bit 1
201; 0: map x, y to the desktop
202; 1: map x, y relative to EPM window
203;
204; When caller does not pass a valid FLAGS an artifical, temporary value is set: -2.
205; When FLAGS is -2 the code will
206; a) determine if there is more space above or below the ROW
207; b) Set FLAGS, and Y so that the listbox will appear just above or just
208; below ROW depending on where there is more room
209;
210defproc ListBox( title, listbuf)
211 universal app_hini
212
213 if leftstr( listbuf, 1) = \0 then
214 liststuff = substr( listbuf, 2, 8)
215 flags = substr( listbuf, 10)
216 if not IsNum( flags) then
217 flags = -2 -- artificial value indicating "don't care"
218 endif
219 else
220 listbuf = listbuf\0
221 liststuff = atol( length( listbuf) - 1) || -- length of list
222 address( listbuf) -- list
223 flags = -2 -- artificial value indicating "don't care"
224 endif
225 title = title\0
226
227 if arg( 3) <> '' then -- button names were specified
228 parse value arg( 3) with delim 2 but1 (delim) but2 (delim) but3 (delim) but4 (delim) but5 (delim) but6 (delim) but7 (delim)
229 nb = 0
230 if but1 <> '' then
231 but1 = but1\0
232 nb = nb + 1
233 else
234 'SayError ListBox:' BUTTON_ERROR__MSG
235 return 0
236 endif
237 if but2 <> '' then
238 but2 = but2\0
239 nb = nb + 1
240 else
241 but2 = \0
242 endif
243 if but3 <> '' then
244 but3 = but3\0
245 nb = nb + 1
246 else
247 but3 = \0
248 endif
249 if but4 <> '' then
250 but4 = but4\0
251 nb = nb + 1
252 else
253 but4 = \0
254 endif
255 if but5 <> '' then
256 but5 = but5\0
257 nb = nb + 1
258 else
259 but5 = \0
260 endif
261 if but6 <> '' then
262 but6 = but6\0
263 nb = nb + 1
264 else but6 = \0
265 endif
266 if but7 <> '' then
267 but7 = but7\0
268 nb = nb + 1
269 else
270 but7 = \0
271 endif
272 else -- default buttons
273 but1 = ENTER__MSG\0
274 but2 = CANCEL__MSG\0
275 but3 = \0
276 but4 = \0
277 but5 = \0
278 but6 = \0
279 but7 = \0
280 nb = 2
281 endif
282
283 if arg() > 5 then -- were height and width specified
284 height = arg( 6) -- height was passed
285 else
286 height = 0 -- default: 0 = use listbox default
287 endif
288 if height < 4 then
289 height = 4 -- internal default is to show 4 lines
290 endif
291
292 if arg() > 6 then -- were height and width specified
293 width = arg( 7) -- width was passed
294 else
295 width = 0 -- default: 0=use listbox default
296 endif
297
298 -- Row and col count from the lower left corner of the edit window
299 row = 0
300 col = 0
301 fAtCursor = 0
302 if arg() > 3 then -- row and col were passed
303 row = arg( 4)
304 col = arg( 5)
305 endif
306 if row = 0 then
307 row = (.windowheight - (height + 4)) % 2 -- centered
308 elseif leftstr( translate( row), 1) = 'C' then
309 row = .cursory -- beneath the cursor
310 fAtCursor = 1
311 endif
312 if col = 0 then
313 col = (.windowwidth - Max( width, 30)) % 2 -- centered
314 elseif leftstr( translate( col), 1) = 'C' then
315 col = .cursorx -- beneath the cursor
316 fAtCursor = 1
317 endif
318 --dprintf( 'row = 'row', col = 'col', height = 'height', width = 'width', .windowheight = '.windowheight', .windowwidth = '.windowwidth)
319
320 if arg() > 7 then
321 selectbuf = leftstr( arg( 8), 255, \0)
322 else
323 selectbuf = copies( \0, 255)
324 endif
325
326 --parse value entrybox( 'Enter row col addl heightadjust') with row col jbsu hadj
327 --parse value entrybox( 'Enter row col adj') with row col jbsu
328 call dprintf( 'listbox', 'curx cury: '.cursorx .cursory)
329 call dprintf( 'listbox', 'col row: 'col row)
330 --call listbox2( title, listbuf, arg( 3), row, col, arg( 6), arg( 7))
331 --parse value entrybox( 'Enter comment') with msg
332 --call dprintf( 'listbox', 'Comment: 'msg)
333 -- o .windowy and .windowx are always 0 in EPM
334 -- o screenheight() and screenwidth() return the window dimensions in
335 -- pixels
336 -- o .fontheight and .fontwidth are values in pixel, e.g. for 12.System
337 -- VIO: 16x8
338 -- o Of course the dialog font differs from the edit window font and
339 -- .fontheight and .fontwidth return the size of the edit window font
340 -- o .cursory is 1 when cursor is on top and .windowheight when cursor is
341 -- on bottom, values in lines
342 -- o .cursorx is 1 when cursor is at the left and .windowwidth when cursor
343 -- is at the right edge, values in cols
344
345 -- JBSQ: "flags" does not seem to work as documented.
346 -- Bits 0 and 1 seem to work as follows:
347 -- 00: x, y mapped to desktop, listbox kept on screen
348 -- 01: x mapped to desktop, y = ?, listbox can go off top of screen
349 -- 10: x, y mapped relative to EPM window, listbox stays on screen
350 -- 11: x, y mapped relative to EPM window, y measured down from bottom of EPM window?
351 -- Conclusion: only 00 and 10 (0 and 2 in decimal) seem to work predictably
352
353 if fAtCursor then
354
355 -- Determining the x coordinate works very well using the standard method:
356 x = .fontwidth * col -- convert row and column into...
357
358 -- The y coordinate depends on the height of the dialog font. The old
359 -- method gives bad results:
360 -- y = .windowy + screenheight() - .fontheight * (row + 1) - 4 /* (Add a fudge factor temporarily */
361
362 -- Correct row for 9.WarpSans (standard was either 10.System Proportional
363 -- or 10.System Monospaced). row and .cursory are counted in number of
364 -- lines from the top.
365 desktop_cy = NepmdQuerySysInfo( 'CYSCREEN')
366 if rc then
367 'SayError Error query system screen resolution, rc = 'rc'.'
368 return 'Error query system screen resolution, rc = 'rc'.'
369 endif
370 call dprintf( 'listbox', 'Desktop height /2 = 'desktop_cy (desktop_cy/2))
371 win_data = NepmdQueryWindowPos( EPMINFO_EDITFRAME)
372 if rc then
373 'SayError Error query frame position, rc = 'rc'.'
374 return 'Error query frame position, rc = 'rc'.'
375 endif
376 parse value win_data with fwindowx fwindowy fwindowcx fwindowcy
377 call dprintf( "listbox", 'SWP F: 'fwindowx fwindowy fwindowcx fwindowcy)
378 win_data = NepmdQueryWindowPos( EPMINFO_EDITCLIENT)
379 if rc then
380 'SayError Error query client position, rc = 'rc'.'
381 return 'Error query client position, rc = 'rc'.'
382 endif
383 parse value win_data with cwindowx cwindowy cwindowcx cwindowcy -- the x and y are relative to the frame
384 windowx = cwindowx + fwindowx -- so add in the frame x to get absolute client x
385 windowy = cwindowy + fwindowy -- so add in the frame y to get absolute client y
386 call dprintf( 'listbox', 'SWP C: 'cwindowx cwindowy cwindowcx cwindowcy)
387
388 -- Estimate the height of the entire listbox dialog
389 -- The height of additional dialog controls takes about 7 lines of
390 -- 9.WarpSans (same height as 12.System VIO, which has 16x8).
391 --addpixels = 102 + (50 * (nb > 4))
392 addpixels = 122 + (40 * (nb > 4)) -- 40 per row of buttons + 122 for other "overhead" pixels
393 boxfontheight = 16 -- value in pels = pixels
394 boxcy = height * ( boxfontheight ) + addpixels
395 call dprintf( 'listbox', 'wdwhgt hgt boxcy addl: '.windowheight height boxcy addpixels)
396
397 row_y = .fontheight * (.windowheight - (row - 1))
398 SpaceBelowCursor = windowy + row_y
399 call dprintf( 'listbox', 'row_y Spcbelow: 'row_y SpaceBelowCursor)
400 if flags < 0 then
401 if SpaceBelowCursor < (desktop_cy / 2) then
402 -- Position listbox window above row, col
403 wanty = row_y
404 topofwin = 0
405 too_much = 0
406 if flags < 0 then
407 topofwin = wanty + boxcy + windowy
408 too_much = topofwin - desktop_cy
409 if too_much > 0 then
410 height = height - (too_much + boxfontheight - 1) % boxfontheight
411 endif
412 flags = 0
413 endif
414 call dprintf( 'listbox', 'Above cursor::wanty top too adjh: 'wanty topofwin too_much height)
415 else
416 -- Position listbox window below row, col
417 wanty = row_y - .fontheight
418 if flags < 0 then
419 too_much = wanty + windowy - boxcy -- - 10 -- fudge factor
420 if too_much < 0 then
421 height = (boxcy + too_much - addpixels) % boxfontheight
422 endif
423 flags = 1
424 endif
425 call dprintf( 'listbox', 'Below cursor::wanty adjh too_much: 'wanty height too_much)
426 endif
427 endif
428 call dprintf( 'listbox', 'flags bit1 winy: 'flags ((flags % 2) // 2) windowy)
429 if ((flags % 2) // 2) then
430 y = wanty
431 else
432 x = x + windowx
433 y = wanty + windowy
434 endif
435 -- Prevent corrupted window diplays because the cursor is offscreen
436 if (flags < 2) and (x <= -windowx) then
437 x = 1 - windowx
438 endif
439
440 -- With this coordinate determination, the listbox window may be placed
441 -- outside of the frame window. That is intended, since we don't have a
442 -- MDI window. Limiting the listbox window to screen values is done
443 -- automatically by the LISTBOX function.
444
445 else -- not at cursor
446
447 y = .fontheight * row
448 x = .fontwidth * col
449 flags = 2 -- gives best results for centering in the edit window
450
451 endif
452
453 if getpminfo( EPMINFO_EDITFRAME) then
454 handle = EPMINFO_EDITFRAME
455 else -- If frame handle is 0, use edit client instead.
456 handle = EPMINFO_EDITCLIENT
457 endif
458 call dprintf( 'listbox', 'final::flags col row x y: 'flags col row x y)
459
460 call dynalink32( ERES_DLL, -- list box control in EDLL dyna
461 'LISTBOX', -- function name
462 GethWndC( handle) || -- edit frame handle
463 atol( flags) ||
464 atol( x) || -- coordinates
465 atol( y) ||
466 atol( height) ||
467 atol( width) ||
468 atol( nb) ||
469 address( title) || -- list box dialog title
470 address( but1) || -- text to appear in buttons
471 address( but2) ||
472 address( but3) ||
473 address( but4) ||
474 address( but5) ||
475 address( but6) ||
476 address( but7) ||
477 liststuff ||
478 address( selectbuf) || -- return string buffer
479 atol( app_hini)) -- handle to INI file
480
481 'PostMe HighlightCursor'
482 parse value selectbuf with Button 2 Select \0
483 Button = asc( Button)
484
485 RetVal = Select
486 do once = 1 to 1
487 if arg( 6) then -- New way
488 RetVal = selectbuf
489 elseif Button = 0 | Button = 2 then -- Old way
490 RetVal = ''
491 elseif Button <> 1 then
492 RetVal = Button
493 else
494 EOS = pos( \0, selectbuf, 2) -- chr( 0) signifies End Of String
495 if not EOS then
496 RetVal = 'Error'
497 endif
498 endif
499 enddo
500 'PostMe SetFocusToEditClient'
501 return RetVal
502
503/*
504; ---------------------------------------------------------------------------
505; Sample command that uses the old list box function
506defc listdemo
507 select = ListBox( 'My List',
508 '/Bryan/Jason/Jerry Cuomo/Ralph/Larry/Richard/');
509 if select == '' then
510 'SayError Nothing Selected'
511 else
512 'SayError List box selection = "'select'"'
513 endif
514
515; ---------------------------------------------------------------------------
516; Sample command that uses the new list box function
517defc listdemo2
518 sayerror 'Selected entry 3; default button 2; help panel 9300.'
519 selectbuf = ListBox( 'My List',
520 '/One/Two/Three',
521 '/Go to/Delete/Cancel/Help',
522 0, 0, 0, 0,
523 GethWndC( APP_HANDLE) || atoi( 3) || atoi( 2) || atoi( 9300) ||
524 'Prompt text');
525 -- Parse return string
526 parse value selectbuf with Button 2 Select \0
527 Button = asc( Button)
528
529 if Button = 0 then
530 'SayError Nothing selected'
531 else
532 'SayError Button' Button 'was pressed; string =' Select
533 endif
534*/
535
536; ---------------------------------------------------------------------------
537/*
538ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
539³ ³
540³ What's it called: Listbox_Buffer_From_File ³
541³ ³
542³ What does it do : Inserts contents of a temp file into a buffer, ready for ³
543³ a call to listbox(). Quits the source file. Returns '' ³
544³ if no problems. ³
545³ ³
546³ startfid - the starting fileid to which we return ³
547³ bufhndl - (output) the buffer handle ³
548³ noflines - (output) number of lines inserted in buffer ³
549³ usedsize - (output) amount of space used in the buffer ³
550³ ³
551³ Who and when : Larry Margolis 1994/08/29 ³
552³ ³
553ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
554Larry Margolis
555*/
556; o startfid can now be empty if activating a specified file should be
557; suppressed.
558; o buffer( PUTBUF) reads current file into a buffer. The first line is
559; ignored to handle the empty line 'xcom e' added when creating a file.
560; o This proc ensures now that the first line is empty.
561defproc ListBox_Buffer_From_File( startfid, var bufhndl, var noflines, var usedsize)
562 -- Ensure that first line is empty.
563 if textline( 1) <> '' then
564 -- Insert an empty line before line 1.
565 insertline '', 1
566 endif
567
568 -- Check buffer size.
569 buflen = filesize() + .last + 1
570 if buflen > MAXBUFSIZE then
571 'SayError 'LIST_TOO_BIG__MSG '(' buflen '>' MAXBUFSIZE ')'
572 buflen = MAXBUFSIZE
573 endif
574
575 -- Create a private buffer.
576 bufhndl = buffer( CREATEBUF, 'LISTBOX', buflen, 1)
577 if not bufhndl then
578 'SayError CREATEBUF' ERROR_NUMBER__MSG RC
579 return rc
580 endif
581
582 -- Copy lines of current file to the buffer. Omit line 1.
583 noflines = buffer( PUTBUF, bufhndl, 1, 0, APPENDCR)
584 buf_rc = rc
585
586 -- Close temporary file and switch to the specified startfid.
587 .modify = 0
588 'xcom quit'
589 if startfid <> '' then
590 activatefile startfid
591 endif
592
593 -- Check if lines were added.
594 if not noflines then
595 'SayError PUTBUF' ERROR_NUMBER__MSG buf_RC
596 return buf_RC
597 endif
598
599 -- Set buffer size var.
600 usedsize = buffer( USEDSIZEBUF, bufhndl)
601
602; ---------------------------------------------------------------------------
603/*
604ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
605³Outdated description: ³
606³ What's it called: EntryBox ³
607³ ³
608³ What does it do : Creates an application-modal dialog box. ³
609³ The dialog box contains a entry field and 2 push buttons.³
610³ (Up to 4 as of EPM 5.21 / 5.50. See below.) ³
611³ ³
612³ hwnd - handle of owner window ³
613³ title - question to appear on dialog title bar ³
614³ x, y - coordinates of lower left of entry box ³
615³ if (0, 0) then centered to screen. ³
616³ cols - approximate number of cols in entry field ³
617³ in PM font characters ³
618³ max - maximum number of chars ³
619³ entry - entry field string returned ³
620³ ³
621³ Who and when : Gennaro (Jerry) Cuomo 4-89 ³
622³ ³
623ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
624
625EPM 5.21 / 5.50 added some new features to the ETOOLKIT interface. Parameter
6266 is used to expose this to the caller of EntryBox(). If present, it is a string
627consisting of: selected_button# || help_ID || handle || prompt.
628
629Larry Margolis / John Ponzo 6/91
630
631Flags = param7
632
633 LAM: New feature for EPM 6.01a: Can pass entryfield flags as a 7th
634 parameter. Primarily of interest for getting passwords:
635 defc pw =
636 pw = EntryBox( 'Enter Password',
637 '', -- Buttons
638 '', -- Entry text
639 '', -- Cols
640 '', -- Max len
641 '', -- Return buffer
642 140) -- ES_UNREADABLE + ES_AUTOSCROLL + ES_MARGIN
643 'SayError Password = "'pw'"'
644
645
646SelectBuf = buffer for input (param6) and output (selectbuf)
647
648 param6 = selected_button# || help_ID || handle || prompt
649
650 o The help_ID must be specified as atoi( help_ID).
651 o The handle should be specified as GethWndC( APP_HANDLE).
652 o The help panel is opened via F1 or via the help button,
653 - if the help panel exists in or was added to EPM.HLP,
654 - if the help_ID was correctly specified (see the IPF source for
655 the help ids) as atoi( help_ID),
656 - if GethWndC( APP_HANDLE) was specified as handle.
657 o If no help id exists in the .hlp file, specify atoi( 0). The handle
658 can then be specified as atol( 0).
659 o If a help_ID was specified, the last button works as help key,
660 independent of its text.
661
662 Example 1
663
664 buttons = '/'OK__MSG'/'CANCEL__MSG'/'HELP__MSG or
665 '/'OK__MSG'/'CANCEL__MSG'/'HELP__MSG'/'
666 param6 = atoi( 1) || atoi( 32115) || GethWndC( APP_HANDLE) || TREE_DIR_PROMPT__MSG
667
668 Example 2
669
670 buttons = '/~Set/~Reset/'CANCEL__MSG
671 param6 = atoi( 1) || atoi( 0) || atol( 0) || Text
672
673 Parsing the returned buffer
674
675 parse value EntryBox( ...) with SelectedButton 2 NewEntryText \0
676 SelectedButton = \1 for button #1, \2 for button #2, ...
677 or SelectedButton = asc( SelectedButton) for numbers.
678
679PosFlag = '' | 0 | 1
680
681 o It's possible to change the centering of the entry box by using other
682 values than 0 for x and y in dynalink32. That doesn't work as expected
683 and has a side effect.
684 o The flag was added for specifying if the dialog should open with at
685 (x, y) = (128, 72) = col 17, 4.5 lines above the bottom line. Then
686 PosFlag should be specified as 1. The default centered behavior can be
687 specified with PosFlag = 0 or with omitting it.
688 o Side efect: The right edge of the dialog is not painted correctly.
689 That seem to depend on the max. lengths of title, prompt and entry.
690 The texts may get invisible at the right edge.
691*/
692
693; Syntax: entrybox title [,buttons][,entrytext][,cols][,maxchars][,param6][,flags][,posflag]
694defproc EntryBox( title)
695
696 title = title\0
697
698 nb = 2 -- default number of buttons
699 if arg( 2) <> '' then -- button names were specified
700 parse value arg( 2) with delim 2 but1 (delim) but2 (delim) but3 (delim) but4 (delim)
701 if but1 <> '' then
702 but1 = but1\0
703 else
704 'SayError EntryBox:' BUTTON_ERROR__MSG
705 return 0
706 endif
707 if but2 <> '' then
708 but2 = but2\0
709 else
710 but2 = ''\0
711 endif
712 if but3 <> '' then
713 but3 = but3\0
714 nb = 3
715 else
716 but3 = ''\0
717 endif
718 if but4 <> '' then
719 but4 = but4\0
720 nb = 4
721 else
722 but4 = ''\0
723 endif
724 else
725 but1 = \0
726 but2 = \0
727 but3 = \0
728 but4 = \0
729 endif
730
731 if arg() >= 3 then
732 entrytext = arg( 3)\0
733 else
734 entrytext = \0
735 endif
736
737 columns = arg( 4) -- width of entry field in approx. columns - no effect
738 if columns < 0 then
739 columns = 30
740 endif
741
742 if arg() >= 5 & arg( 5) <> '' & arg( 5) <> 0 then
743 maxchars = Max( 1, arg( 5), length( arg( 3)))
744 else
745 maxchars = 254
746 endif
747
748 -- Null-terminate param6 -- In : selectbuf = atoi( selected_button#) || atoi( help_ID) || (handle = GethWndC( APP_HANDLE), for help only) || prompt
749 if arg() > 5 then -- Out: selectbuf = (pressed_button# = asc( leftstr( selectbuf, 1))) || entrytext \0
750 selectbuf = leftstr( arg( 6), MAXCOL, \0)
751 else
752 selectbuf = copies( \0, MAXCOL)
753 endif
754
755 if arg() >= 7 & arg( 7) <> '' & arg( 7) <> 0 then
756 flags = arg( 7)
757 else
758 flags = 0
759 endif
760
761 if arg() >= 8 & arg( 8) <> '' & arg( 8) <> 0 then
762 x = 1 -- 128 = col 17, side effect: right edge of the dialog is not painted correctly, depends on text length
763 y = 1 -- 72 = 4.5 lines from the buttom
764 else
765 x = 0 -- centered
766 y = 0 -- centered
767 endif
768
769 call dynalink32( ERES_DLL, -- entry box control in EDLL dyna
770 'ENTRYBOX', -- function name
771 GethWndC( EPMINFO_EDITFRAME)|| -- edit frame handle
772 address( title) || --
773 atol( x) || -- x coordinate (0 = centered or any other value for x = 128) > mixed
774 atol( y) || -- y coordinate (0 = centered or any other value for y = 72) > up?
775 atol( columns) || --
776 atol( maxchars) || --
777 address( entrytext) || -- (optional text in entry field)
778 atoi( nb) || -- Number of buttons, and
779 atoi( flags) || -- flags: mpfrom2short( flags, nb)
780 address( but1) || -- (optional button 1 text)
781 address( but2) || -- (optional button 2 text)
782 address( but3) || -- (optional button 3 text)
783 address( but4) || -- (optional button 4 text)
784 address( selectbuf)) -- return string buffer
785
786 'PostMe HighlightCursor'
787 -- Parse return string
788 parse value selectbuf with Button 2 Select \0
789 Button = asc( Button)
790
791 RetVal = Select
792 do once = 1 to 1
793 if arg( 6) then -- New way
794 RetVal = selectbuf
795 elseif Button = 0 | Button = 2 then -- Old way
796 RetVal = ''
797 elseif Button <> 1 then
798 RetVal = Button
799 else
800 EOS = pos( \0, selectbuf, 2) -- chr( 0) signifies End Of String
801 if not EOS then
802 RetVal = 'Error'
803 endif
804 endif
805 enddo
806 'PostMe SetFocusToEditClient'
807 return RetVal
808
809; ---------------------------------------------------------------------------
810-- Unused
811/*
812; LineStr is parsed and values for Filename, Line, Col, SearchStr are
813; returned. Vars for Filename, Line, Col, SearchStr must be specified, even
814; when they are expected to be returned with empty values.
815; Syntax of LineStr:
816; <filename>
817; <filename> (<line>)
818; <filename> (<line>,<col>)
819; <filename> /<searchstr>
820defproc DialogParseListBoxLine( LineStr, var Filename, var Line, var Col, var SearchStr)
821 do once = 1 to 1
822 Filename = ''
823 Line = ''
824 Col = ''
825 SearchStr = ''
826 LineStr = strip( LineStr)
827 if leftstr( LineStr, 1) = '"' then
828 parse value LineStr with '"'Filename'"' '('PosStr')'
829 else
830 parse value LineStr with Filename '('PosStr')'
831 endif
832 if PosStr <> '' then
833 parse value PosStr with Line','Col
834 Filename = strip( Filename)
835 Line = strip( Line)
836 Col = strip( Col)
837 leave
838 endif
839 if leftstr( LineStr, 1) = '"' then
840 parse value LineStr with '"'Filename'"' '/'SearchStr
841 else
842 parse value LineStr with Filename '/'SearchStr
843 endif
844 if SearchStr <> '' then
845 Filename = strip( Filename)
846 SearchStr = strip( SearchStr)
847 leave
848 endif
849 enddo
850
851 return
852*/
853; ---------------------------------------------------------------------------
854; This passes its args to either Open or Edit, depending on the pressed
855; Ctrl key. Being a defc, it allows for posting.
856defc DialogLoadFile
857 EditArgs = strip( arg( 1))
858 if CtrlIsDown() then
859 Cmd = 'Open'
860 else
861 Cmd = 'Edit'
862 endif
863 Cmd EditArgs
864
865; ---------------------------------------------------------------------------
866; This loads or activates a background bitmap. Checks for valid filename
867; added, because otherwise initialization on EPM's startup would stop on a
868; non-valid OS/2 file.
869defc Load_Dt_Bitmap
870 universal bm_filename
871 universal bitmap_present
872 BmpFile = arg( 1)
873 if BmpFile = '' then
874 -- load default file
875 elseif substr( BmpFile, 2, 2) = ':\' & IsOs2Bmp( BmpFile) then -- if fully qualified and valid
876 -- load specified file
877 else
878 'SayError Filename for background bitmap not valid'
879 BmpFile = ''
880 -- load default file
881 endif
882
883 if BmpFile = '' then
884 -- load the default bitmap
885 call windowmessage( 0,
886 getpminfo( EPMINFO_EDITCLIENT),
887 5454, 0, 0)
888 else
889 -- load an external bitmap
890 call windowmessage( 0,
891 getpminfo( EPMINFO_EDITCLIENT),
892 5499, -- EPM_EDIT_SETDTBITMAPFROMFILE
893 put_in_buffer( BmpFile),
894 0)
895 endif
896 bm_filename = BmpFile
897 bitmap_present = 1
898
899; ---------------------------------------------------------------------------
900; Doesn't work with eCS, ...?
901/*
902defc drop_bitmap, drgdrptyp_Bitmap, dragdrop_bmp
903 universal bm_filename
904 parse arg x y bm_filename
905 'Load_Dt_Bitmap' bm_filename
906*/
907
908; ---------------------------------------------------------------------------
909defc SetBackgroundBitmap
910 universal bitmap_present
911 universal bm_filename
912 universal app_hini
913 universal appname
914 arg1 = strip( arg( 1))
915 fSetBmp = 0
916 fNewBmp = 0
917 if upcase( arg1) = 'SELECT' then
918 BitmapDir = ''
919 if bm_filename > '' then
920 lp = lastpos( '\', bm_filename)
921 BitmapDir = substr( bm_filename, 1, lp - 1)
922 endif
923 if NepmdDirExists( BitmapDir) <> 1 then
924 BootDrive = NepmdQuerySysInfo( 'BOOTDRIVE')
925 BitmapDir = BootDrive'\os2\bitmap'
926 endif
927 'FileDlg Select a background bitmap file, SetBackgroundBitmap, 'BitmapDir'\*.bmp'
928 return
929 elseif wordpos( upcase( arg1), '0 OFF') then
930 bitmap_present = 0
931 fSetBmp = 1
932 elseif wordpos( upcase( arg1), '1 ON') then
933 bitmap_present = 1
934 fSetBmp = 1
935 elseif wordpos( upcase( arg1), 'TOGGLE') then
936 bitmap_present = not bitmap_present
937 fSetBmp = 1
938 else
939 fNewBmp = 1
940 endif
941
942 if fSetBmp then
943 if bitmap_present then
944 -- activate it
945 'Load_Dt_Bitmap' bm_filename
946 else
947 -- deactivate it
948 call windowmessage( 0,
949 getpminfo( EPMINFO_EDITCLIENT),
950 5498,
951 0,
952 0)
953 endif
954 endif
955
956 if fNewBmp then
957 'Load_Dt_Bitmap' arg( 1)
958 if bitmap_present then
959 KeyPath = '\NEPMD\User\Appearance\BackgroundBitmap\Filename'
960 call WriteConfigKey( KeyPath, bm_filename)
961 endif
962 endif
963
964 if fSetBmp | fNewBmp then
965 KeyPath = '\NEPMD\User\Appearance\BackgroundBitmap'
966 call WriteConfigKey( KeyPath, bitmap_present)
967 endif
968
969; ---------------------------------------------------------------------------
970defproc IsOs2Bmp
971 SigList = 'BMP BM BA'
972 arg1 = strip( arg( 1))
973 ret = 0
974 if rightstr( upcase( arg1), 4) = '.BMP' then
975 Result = CheckSig( arg( 1), SigList)
976 if Result = 1 then
977 ret = 1
978 elseif rc <> 0 then
979 --'SayError CheckSig returned rc = 'rc
980 endif
981 endif
982 return ret
983
984; ---------------------------------------------------------------------------
985defproc QueryControl( controlid)
986 return windowmessage( 1,
987 getpminfo( EPMINFO_EDITCLIENT), -- Send message to edit client
988 5388, -- EPM_EDIT_CONTROLTOGGLE
989 controlid,
990 1)
991
992; ---------------------------------------------------------------------------
993defc CursorOff
994 call CursorOff() -- Turn cursor off
995
996; ---------------------------------------------------------------------------
997defproc CursorOff -- Turn cursor off
998 'togglecontrol 14 0' -- doesn't work in current EPM
999
1000; ---------------------------------------------------------------------------
1001; Trim window so it's an exact multiple of the font size.
1002defc Trim
1003 call WindowSize1( .windowheight, .windowwidth, 0, 0, 1)
1004
1005; EPM bug:
1006; o During startup, before file loading, .windowwidth, .windowheight and
1007; .fontwidth are not set correctly. During defmain, after initialization,
1008; they have alternating values. That's why Trim and WindowSize1 can't be
1009; used at that point. It works later.
1010; o See MAIN.E for a workaround with NepmdQueryWindowPos and
1011; NepmdSetFrameWindowPos.
1012
1013; ---------------------------------------------------------------------------
1014defc WindowSize1
1015 parse arg row col x y flag junk
1016 if x = '' | junk <> '' then
1017 'SayError '-263 -- Invalid argument
1018 else
1019 call WindowSize1( row, col, x, y, flag)
1020 endif
1021
1022; ---------------------------------------------------------------------------
1023defproc WindowSize1( row, col, x, y)
1024
1025 if upcase( leftstr( row, 1)) = 'P' then -- Already in pels
1026 cy = substr( row, 2)
1027 else
1028 cy = .fontheight * row -- convert row into y coordinate in pels
1029 endif
1030 if upcase( leftstr( col, 1)) = 'P' then -- Already in pels
1031 cx = substr( col, 2)
1032 else
1033 cx = .fontwidth * col -- convert col into x coordinate in pels
1034 endif
1035
1036 if arg( 5) <> '' then
1037 opts = arg( 5)
1038 else
1039 opts = 3 -- Default = SWP_SIZE ( 1) + SWP_MOVE ( 2)
1040 endif
1041
1042 if opts // 2 then -- Don't bother calculating unless SWP_SIZE on
1043 swp1 = copies( \0, 36)
1044 swp2 = swp1
1045 call dynalink32( 'PMWIN',
1046 '#837',
1047 GethWndC( EPMINFO_EDITCLIENT) ||
1048 address( swp1))
1049 call dynalink32( 'PMWIN',
1050 '#837',
1051 GethWndC( EPMINFO_EDITFRAME) ||
1052 address( swp2))
1053 cx = cx + ltoa( substr( swp2, 9, 4), 10) - ltoa( substr( swp1, 9, 4), 10)
1054 cy = cy + ltoa( substr( swp2, 5, 4), 10) - ltoa( substr( swp1, 5, 4), 10)
1055 endif
1056
1057 call dynalink32( 'PMWIN',
1058 '#875',
1059 GethWndC( EPMINFO_EDITFRAME) ||
1060 atol( 3) || /* HWND_TOP */
1061 atol( x) ||
1062 atol( y) ||
1063 atol( cx) ||
1064 atol( cy) ||
1065 atol( opts)) /* SWP_MOVE | SWP_SIZE */
1066
1067; ---------------------------------------------------------------------------
1068; - This accepts arg( 1) = flag for JustInstalled (1 or other).
1069; - It trims the frame window size to full cols and lines. That avoids some
1070; scrolling on moving the cursor.
1071; - It checks if the frame window is completely outside of the desktop and
1072; then retrieves the frame window.
1073; - On retrieving the frame window or if JustInstalled, the frame window
1074; is centered on the desktop.
1075defc TrimFrameWindow
1076 JustInstalled = (strip( arg( 1)) = 1)
1077
1078 -- Query window pos. and size
1079 -- (Desktop workarea would require to use the undocumented PMMERGE.5469
1080 -- function WinQueryDesktopWorkarea. See XWP for that.)
1081 cxd = NepmdQuerySysInfo( 'CXSCREEN')
1082 cyd = NepmdQuerySysInfo( 'CYSCREEN')
1083 FramePos = NepmdQueryWindowPos( EPMINFO_EDITFRAME)
1084 ClientPos = NepmdQueryWindowPos( EPMINFO_EDITCLIENT)
1085 parse value FramePos with xf yf cxf cyf
1086 parse value ClientPos with xc yc cxc cyc
1087 dcx = cxf - cxc
1088 dcy = cyf - cyc
1089
1090 Flag = 3 -- Change pos. and size
1091
1092 -- New frame window size
1093 -- EPM bug: Sometimes .fontwidth is set to 3.
1094 -- Ignore small sizes:
1095 if .fontwidth > 3 then
1096 -- Trim window so it's an exact multiple of the font size. This should
1097 -- avoid scrolling caused by temp. cursor pos. changes and restore.
1098 KeyPath = '\NEPMD\User\EditWindow\MaxCols'
1099 MaxCols = QueryConfigKey( KeyPath)
1100 if MaxCols > 0 then
1101 -- Limit edit window width to MaxCols and trim to full cols
1102 Newcxc = Min( MaxCols, cxc % .fontwidth) * .fontwidth
1103 else
1104 -- Trim to full cols
1105 Newcxc = (cxc % .fontwidth) * .fontwidth
1106 endif
1107 -- Trim to full lines
1108 Newcyc = (cyc % .fontheight) * .fontheight
1109
1110 -- New frame window width and height
1111 Newcxf = Newcxc + dcx
1112 Newcyf = Newcyc + dcy
1113 else
1114 -- Keep old frame window size
1115 Flag = Flag - 1
1116 Newcxf = cxf
1117 Newcyf = cyf
1118 endif
1119
1120 -- New frame window pos.
1121 -- Check if frame window is completely out of the desktop
1122 fOutside = 0
1123 do once = 1 to 1
1124 -- Right frame window edge
1125 if xf + Newcxf < 0 then
1126 fOutside = 1
1127 -- Left frame window edge
1128 elseif xf > cxd then
1129 fOutside = 1
1130 -- Bottom frame window edge
1131 elseif yf > cyd then
1132 fOutside = 1
1133 -- Top frame window edge
1134 elseif yf + Newcyf < 0 then
1135 fOutside = 1
1136 endif
1137 enddo
1138 if fOutside | JustInstalled then
1139 -- Limit frame window size to the desktop size
1140 Newcxf = Min( cxd, Newcxf)
1141 Newcyf = Min( cyd, Newcyf)
1142 -- Center frame window
1143 Newxf = Max( 0, cxd - Newcxf) / 2
1144 Newyf = Max( 0, cyd - Newcyf) / 2
1145 else
1146 -- Keep frame window pos.
1147 Flag = Flag - 2
1148 Newxf = xf
1149 Newyf = yf
1150 endif
1151
1152 -- Set new frame window pos. and/or size
1153 if Flag > 0 then
1154 call NepmdSetFrameWindowPos( Newxf, Newyf, Newcxf, Newcyf, Flag)
1155 endif
1156
1157; ---------------------------------------------------------------------------
1158; arg( 1) = number. Opens dialog if no arg.
1159defc LimitEditWindowWidth
1160 universal menuloaded
1161
1162 do once = 1 to 1
1163 KeyPath = '\NEPMD\User\EditWindow\MaxCols'
1164 CurNum = QueryConfigKey( KeyPath)
1165 Num = strip( arg( 1))
1166 if IsNum( Num) then
1167 NewNum = Num
1168 if NewNum = 0 then
1169 call DeleteConfigKey( KeyPath)
1170 else
1171 call WriteConfigKey( KeyPath, NewNum)
1172 endif
1173 else
1174 Title = 'Maximal window width on start'
1175 Buttons = '/~Set/~Reset/'CANCEL__MSG
1176 Text = 'Width in columns. Specify 0 for no limitation.'
1177 Text = Text''copies( ' ', Max( 0, 100 - length( Text)))
1178 Entry = CurNum
1179 parse value EntryBox( Title,
1180 Buttons,
1181 Entry,
1182 0,
1183 240,
1184 atoi( 1) || atoi( 0) || atol( 0) ||
1185 Text) with Button 2 NewNum \0
1186 -- Parse return string
1187 Button = asc( Button)
1188 NewNum = strip( NewNum)
1189 if Button = 1 then
1190 if NewNum <> CurNum then
1191 if IsNum( NewNum) then
1192 call WriteConfigKey( KeyPath, NewNum)
1193 else
1194 'SayError Max. number of cols not changed.'
1195 endif
1196 endif
1197 elseif Button = 2 then
1198 call DeleteConfigKey( KeyPath)
1199 NewNum = ''
1200 else
1201 leave
1202 endif
1203 endif
1204 if menuloaded & NewNum <> CurNum then
1205 CurNum = QueryConfigKey( KeyPath)
1206 Text = GetConditionalMenuText( 'startwithmaxcols', CurNum)
1207 SetMenuVarTextFromText( 'startwithmaxcols', Text, CurNum)
1208 endif
1209 enddo
1210
1211; ---------------------------------------------------------------------------
1212compile if 0 -- Unused, so don't waste space. LAM
1213defc QControl
1214 if QueryControl( arg( 1)) then
1215 'SayError control on'
1216 else
1217 'SayError control off'
1218 endif
1219compile endif
1220
1221; ---------------------------------------------------------------------------
1222; Opens a dialog to edit and apply font styles.
1223; This dialog uses several callback commands that are defined below.
1224defc FontList
1225 call windowmessage( 0,
1226 getpminfo( APP_HANDLE),
1227 5130, -- EPM_POPFONTDLG
1228 Put_In_Buffer( queryfont( .font)'.'Trunc( .textcolor // 16)'.'.textcolor % 16),
1229 0)
1230
1231; ---------------------------------------------------------------------------
1232/*
1233ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1234³ what's it called: commandline syntax: commandline [optional text] ³
1235³ ³
1236³ what does it do : ask EPM.EXE to pop up its internal commandline control. ³
1237³ This is done by posting a EPM_POPCMDLINE message to the ³
1238³ EPM Book window. ³
1239³ An optional string of text can be specified. If a string³
1240³ is specified then it will be inserted on the command line³
1241³ ³
1242³ (All EPM_EDIT_xxx messages are defined in the ETOOLKT ³
1243³ PACKAGE available on PCTOOLS.) ³
1244³ ³
1245³ who and when : Jerry C. 2/27/89 ³
1246ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1247*/
1248
1249defc CommandLine -- The application will free the buffer allocated by this macro
1250 parse arg cmd -- try to keep trailing spaces
1251 call windowmessage( 0,
1252 getpminfo( APP_HANDLE),
1253 5124, -- EPM_POPCMDLINE
1254 0,
1255 Put_In_Buffer( cmd)) -- trailing spaces are always stripped before execution
1256
1257; ---------------------------------------------------------------------------
1258/*
1259ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1260³ what's it called: PostCmdToEditWindow( cmd, winhandle [, mp2 [, buflg]] ) ³
1261³ ³
1262³ what does it do : ask EPM.EXE to post a command to an edit window. MP2 is ³
1263³ optional MP2 for the WinPostMsg. Default is 1 (EPM ³
1264³ should free the command buffer). 4 means process ³
1265³ synchronously (not safe), and 8 means that EPM should do ³
1266³ a DosGetBuf to get the buffer. Optional 4th argument is ³
1267³ passed to put_in_buffer (flag for DosAllocSeg; see ³
1268³ put_in_buffer routine for details). ³
1269³ ³
1270³ who and when : Larry M. 7/23/90 ³
1271ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1272*/
1273defproc PostCmdToEditWindow( cmd, winhndl)
1274 if arg( 3) <> '' then
1275 mp2 = arg( 3)
1276 else
1277 mp2 = 1
1278 endif
1279 call windowmessage( 0,
1280 winhndl,
1281 5377, -- EPM_EDIT_COMMAND
1282 Put_In_Buffer( cmd, arg( 4)),
1283 mp2)
1284
1285; ---------------------------------------------------------------------------
1286/*
1287ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1288³ what's it called: PostMe syntax: PostMe command ³
1289³ ³
1290³ what does it do : Ask EPM.EXE to post a command to the current edit window.³
1291³ Useful if you want to send a command on an OPEN but ³
1292³ don't want to tie up the main queue while the command is ³
1293³ executing. By posting the command back to the window, ³
1294³ it will execute from the EI queue, and not keep everyone ³
1295³ else waiting. ³
1296³ ³
1297³ Example of usage: ³
1298³ "open 'PostMe long_running_command'" ³
1299³ ³
1300³ who and when : Larry M. 89/08/14 ³
1301ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1302*/
1303defc PostMe
1304 -- Workaround for posted '*defload*' commands: Execute 'AtNextLoad'
1305 -- instead of 'postme', because 'postme' causes a defload action being
1306 -- executed at the following defselect only. Applies to e.g. TeX Front
1307 -- End's defload.
1308 if pos( 'DEFLOAD', upcase( arg( 1))) then
1309 'AtNextLoad' arg( 1)
1310 else
1311 call PostCmdToEditWindow( arg( 1), getpminfo( EPMINFO_EDITCLIENT))
1312 --dprintf( 'POSTME', 'arg( 1) = 'arg( 1))
1313 endif
1314
1315; See also: HOOKS.E:"defc AfterStartup"
1316
1317; ---------------------------------------------------------------------------
1318defc PostTo
1319 parse arg hwnd Cmd
1320 Cmd = strip( Cmd)
1321 call PostCmdToEditWindow( Cmd, hwnd)
1322
1323; ---------------------------------------------------------------------------
1324; This is not used.
1325/*
1326ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1327³ what's it called: buffer_command syntax: buffer_command buff_address ³
1328³ ³
1329³ what does it do : Executes the command that's stored in the buffer, then ³
1330³ frees the buffer. Useful if you want to send a command ³
1331³ to another window but don't want to worry about length ³
1332³ or invalid characters. ³
1333³ ³
1334³ Example of usage: ³
1335³ 'open buffer_command' put_in_buffer( cmd_string) ³
1336³ ³
1337³ who and when : Larry M. 91/09/03 ³
1338ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1339*/
1340defc Buffer_Command
1341 parse arg buff .
1342 if not buff then -- Null pointer = no command
1343 return
1344 endif
1345 buffer_long = atol( buff)
1346 peekz( buffer_long) -- Get the command from the buffer, & execute it
1347 call dynalink32( 'DOSCALLS', -- Dynamic link library name
1348 '#304', -- Dos32FreeMem
1349 buffer_long)
1350
1351; ---------------------------------------------------------------------------
1352; This is not used.
1353defc Buff_Link
1354 parse arg buff .
1355 if not buff then
1356 return
1357 endif
1358
1359 rc = dynalink32( 'DOSCALLS',
1360 '#302', -- Dos32GetSharedMem
1361 atol( buff) || -- Base address
1362 atol( 1)) -- PAG_READ
1363 if rc then
1364 MessageNWait( 'DosGetSharedMem' ERROR__MSG rc)
1365 endif
1366 buff_ofs = 4
1367 buff_len = ltoa( peek32( buff, 0, 4), 10)
1368 do while buff_len > buff_ofs
1369 link_file = peekz32( buff, buff_ofs)
1370 if upcase( link_file) <> 'EPM.EX' then
1371 if linked( link_file) < 0 then -- Not already linked
1372 'linkverify' link_file
1373 endif
1374 endif
1375 buff_ofs = buff_ofs + length( link_file) + 1 -- +1 for ASCIIZ null
1376 enddo
1377
1378; ---------------------------------------------------------------------------
1379; This us used to allocate mem for a buffer and to copy an E string to it.
1380; E strings are limitted to 1600 B only, so larger buffers don't make sense.
1381defproc Put_In_Buffer( String)
1382 if String = '' then
1383 return 0
1384 endif
1385 StringLen = length( String)
1386 if arg( 2) = '' then
1387 ShareFlags = 83 -- PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_TILE
1388 else
1389 ShareFlags = arg( 2)
1390 endif
1391
1392 -- Initialize string pointer
1393 StringBuffer = '????' -- 4 digits = max. 64 KiB = 16 bit
1394 rcx = dynalink32( 'DOSCALLS', -- Dynamic link library name
1395 '#299', -- Dos32AllocMem
1396 address( StringBuffer) ||
1397 atol( StringLen + 1) || -- Number of bytes requested
1398 atol( ShareFlags))
1399
1400 if rcx then
1401 'SayError 'ERROR__MSG rcx ALLOC_HALTED__MSG
1402 stop
1403 endif
1404
1405 StringBuffer = itoa( substr( StringBuffer, 3, 2), 10)
1406 poke StringBuffer, 0, String -- Copy string to new allocated buf
1407 poke StringBuffer, length( String), \0 -- Add a null at the end
1408 return MpFrom2Short( StringBuffer, 0) -- Return a long pointer to buffer
1409
1410; ---------------------------------------------------------------------------
1411; This command opens a dialog with the past messages.
1412/*
1413ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1414³ what's it called: messagebox syntax: messagebox [optional string] ³
1415³ ³
1416³ what does it do : ask EPM.EXE to pop up its internal message box control. ³
1417³ This is done by posting a EPM_POPMSGBOX message to the ³
1418³ EPM Book window. ³
1419³ An optional string of text can be specified. If a ³
1420³ string is specified then it will be inserted into the ³
1421³ message box. ³
1422³ ³
1423³ (All EPM_EDIT_xxx messages are defined in the ETOOLKT ³
1424³ PACKAGE available on PCTOOLS.) ³
1425³ ³
1426³ who and when : Jerry C. 2/27/89 ³
1427ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1428*/
1429; The application will free the buffer allocated by this macro.
1430defc MessageBox
1431 call windowmessage( 0,
1432 getpminfo( APP_HANDLE),
1433 5125, -- EPM_POPMSGBOX
1434 0,
1435 Put_In_Buffer( arg( 1)))
1436 'PostMe HighlightCursor'
1437
1438; ---------------------------------------------------------------------------
1439; Unused (with WPS anyway)
1440/*
1441ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1442³ what's it called: processdragdrop ³
1443³ ³
1444³ what does it do : this defc is automatically called by the ³
1445³ toolkit when a drag drop event is successfully made ³
1446³ ³
1447³ what are the args: cmdid = 1 - epm edit window ³
1448³ 2 - File icon window (self) ³
1449³ 3 - epm book icon ³
1450³ 4 - system editor ³
1451³ 5 - File Manager folder ³
1452³ 10 - Print manager ³
1453³ ³
1454³ hwnd = handle of target window's frame ³
1455ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1456*/
1457defc ProcessDragDrop
1458 parse arg cmdid hwnd
1459 --dprintf( 'ProcessDragDrop', 'cmdid = 'cmdid', hwnd = 'hwnd)
1460; hwnd = atol_swap( hwnd)
1461
1462 if cmdid = 10 then
1463 call windowmessage( 0,
1464 getpminfo( APP_HANDLE),
1465 5144, -- EPM_PRINTDLG
1466 hwnd = 'M',
1467 0)
1468 elseif cmdid = 1 and hwnd <> getpminfo( EPMINFO_EDITFRAME) and leftstr( .filename, 1) <> '.' then
1469 call PostCmdToEditWindow( 'e '.filename, hwnd, 9, 2) -- Get-able
1470 elseif cmdid = 3 then
1471 if .filename = GetUnnamedFilename() then
1472 name = ''
1473 else
1474 name = .filename
1475 endif
1476 call windowmessage( 0,
1477 getpminfo( APP_HANDLE),
1478 5386, -- EPM_EDIT_NEWFILE
1479 Put_In_Buffer( name, 2), -- share = GETable
1480 9) -- EPM does a GET first & a FREE after.
1481 elseif cmdid = 4 then
1482 call WinMessageBox( SYS_ED__MSG,
1483 SYS_ED1__MSG\10 ||
1484 ' :-)',
1485 16406) -- CANCEL + ICONQUESTION + MB_MOVEABLE
1486 elseif cmdid = 5 then
1487 str = leftstr( '', MAXCOL)
1488 len = dynalink32( 'PMWIN',
1489 '#841', -- 'WINQUERYWINDOWTEXT',
1490 atol( hwnd) ||
1491 atol( MAXCOL) ||
1492 address( str), 2)
1493 p = lastpos( '\', leftstr( str, len))
1494 if p then
1495 str = leftstr( str, p)' = '
1496 call parse_filename( str, .filename)
1497 if Exist( str) then
1498 if 1 <> WinMessageBox( str,
1499 EXISTS_OVERLAY__MSG,
1500 16417) then -- OKCANCEL + CUANWARNING + MOVEABLE
1501 return -- 1 = MB OK
1502 endif
1503 endif
1504 'Save' str
1505 if not rc then
1506 'SayError 'SAVED_TO__MSG str
1507 endif
1508 else
1509 call WinMessageBox( '"'leftstr( str, len)'"',
1510 NO_SLASH__MSG,
1511 16406) -- CANCEL + ICONQUESTION + MB_MOVEABLE
1512 endif
1513 endif
1514
1515; ---------------------------------------------------------------------------
1516/*
1517ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1518³ what's it called: Repaint_Window ³
1519³ ³
1520³ what does it do : send a paint message to the editor. ³
1521³ ³
1522ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1523*/
1524defproc Repaint_Window
1525 call windowmessage( 0,
1526 getpminfo( EPMINFO_EDITCLIENT),
1527 35, -- WM_PAINT
1528 0,
1529 0)
1530
1531; ---------------------------------------------------------------------------
1532/*
1533ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1534³ what's it called: ShowWindow ³
1535³ ³
1536³ what does it do : allows the edit window to become invisible or visible ³
1537³ ³
1538ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1539*/
1540defproc ShowWindow
1541 -- post the EPM_EDIT_SHOW message
1542 call windowmessage( 0,
1543 getpminfo( EPMINFO_EDITCLIENT),
1544 5385,
1545 upcase( arg( 1)) <> 'OFF', -- 0 if OFF, else 1
1546 0)
1547
1548; ---------------------------------------------------------------------------
1549/*
1550ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1551³ what's it called: WinMessageBox ³
1552³ ³
1553³ what does it do : This routine issues a PM WinMessageBox call and returns ³
1554³ the result. ³
1555³ ³
1556ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1557*/
1558; Style:
1559; -- Constants for WinMessageBox
1560; MB_OK = 0 -- Pick one of the following for the
1561; MB_OKCANCEL = 1 -- buttons you want on the message box
1562; MB_RETRYCANCEL = 2
1563; MB_ABORTRETRYIGNORE = 3
1564; MB_YESNO = 4
1565; MB_YESNOCANCEL = 5
1566; MB_CANCEL = 6
1567; MB_ENTER = 7
1568; MB_ENTERCANCEL = 8
1569;
1570; MB_NOICON = 0 -- Add one of the following for the
1571; MB_CUANOTIFICATION = 0 -- icon you want in the message box
1572; MB_ICONQUESTION = 16
1573; MB_ICONEXCLAMATION = 32
1574; MB_CUAWARNING = 32
1575; MB_ICONASTERISK = 48
1576; MB_ICONHAND = 64
1577; MB_CUACRITICAL = 64
1578; MB_QUERY = MB_ICONQUESTION
1579; MB_WARNING = MB_CUAWARNING
1580; MB_INFORMATION = MB_ICONASTERISK
1581; MB_CRITICAL = MB_CUACRITICAL
1582; MB_ERROR = MB_CRITICAL
1583;
1584; MB_DEFBUTTON1 = 0 -- This specifies which button is the
1585; MB_DEFBUTTON2 = 256 -- default if Enter is pressed.
1586; MB_DEFBUTTON3 = 512
1587;
1588; MB_APPLMODAL = 0000 -- Application modal
1589; MB_SYSTEMMODAL = 4096 -- System modal
1590; MB_HELP = 8192
1591; MB_MOVEABLE = 16384 -- The message box can be moved.
1592;
1593; Returns the id of the pressed button:
1594; MBID_OK = 1 -- Message box return codes
1595; MBID_CANCEL = 2 -- (correspond with the button pressed)
1596; MBID_ABORT = 3
1597; MBID_RETRY = 4
1598; MBID_IGNORE = 5
1599; MBID_YES = 6
1600; MBID_NO = 7
1601; MBID_HELP = 8
1602; MBID_ENTER = 9
1603; MBID_ERROR = 65535
1604defproc WinMessageBox( Title, Text)
1605 if arg( 3) then
1606 Style = arg( 3)
1607 else
1608 Style = MB_OK + MB_NOICON * MB_DEFBUTTON1 + MB_APPLMODAL + MB_MOVEABLE
1609 endif
1610 -- The appending of a null char must be processed before the DLL call:
1611 Title = Title\0
1612 Text = Text\0
1613 Button = dynalink32( 'PMWIN',
1614 '#789', -- WinMessageBox
1615 atol( 1) || -- Parent
1616 GethWndC( EPMINFO_EDITFRAME) || -- edit frame handle
1617 address( Text) ||
1618 address( Title) ||
1619 atol( 0) || -- Window
1620 atol( Style))
1621
1622 'PostMe HighlightCursor'
1623 return Button
1624
1625; ---------------------------------------------------------------------------
1626; Syntax: 'ErrorMsgBox ErrorTitle,ErrorText'
1627; Leading and trailing spaces are stripped.
1628; Allow for opening an error MsgBox from REXX.
1629defc ErrorMsgBox
1630 parse arg ErrorTitle','ErrorText
1631 ErrorTitle = strip( ErrorTitle)
1632 ErrorText = strip( ErrorText)
1633 call NepmdErrorMsgBox( ErrorText, ErrorTitle)
1634 'PostMe HighlightCursor'
1635
1636; ---------------------------------------------------------------------------
1637defc InfoMsgBox
1638 parse arg Title','Text
1639 Title = strip( Title)
1640 Text = strip( Text)
1641 Style = MB_OK + MB_INFORMATION + MB_DEFBUTTON1 + MB_MOVEABLE
1642 Button = WinMessageBox( Title, Text, Style)
1643
1644; ---------------------------------------------------------------------------
1645defproc MpFrom2Short( MpHigh, MpLow)
1646 return ltoa( atoi( MpLow)''atoi( MpHigh), 10)
1647
1648; ---------------------------------------------------------------------------
1649; Returns the edit window handle as a 4-byte hex string.
1650; Usually GetHWndC is used. GetHWnd is only used by the outdated ftpload and
1651; ftpsave commands.
1652;
1653; String handling in E language
1654; EdithWnd = '1235:1234' <- Address in string form
1655; atol( EdithWnd) = '11GF' <- Four byte pointer, represented
1656; as its ascii character equivalent.
1657; Flipping (substr( ...)) <- Places 4 bytes in correct order.
1658; Note: 2-byte vars are converted with atoi ie. USHORT
1659; Note: 4-byte vars are converted with atol ie. HWND,HAB
1660defproc GethWnd( w)
1661 --EditHwnd = getpminfo( w) -- get edit window handle
1662 -- o get edit window handle
1663 -- o convert string to string pointer
1664 -- o interchange upper two bytes with lower two bytes. (flip words)
1665 return atol_swap( getpminfo( w))
1666
1667; ---------------------------------------------------------------------------
1668defproc GethWndC( w)
1669 return atol( getpminfo( w))
1670
1671; ---------------------------------------------------------------------------
1672; popbook doesn't work in EPM 6.03b
1673/*
1674defc PopBook
1675 call windowmessage( 0,
1676 getpminfo( APP_HANDLE),
1677 13, -- WM_ACTIVATE
1678 1,
1679 getpminfo( APP_HANDLE))
1680*/
1681
1682; ---------------------------------------------------------------------------
1683defc PrintDlg
1684 call windowmessage( 0,
1685 getpminfo( APP_HANDLE),
1686 5144, -- EPM_PRINTDLG
1687 arg( 1) = 'M',
1688 0)
1689
1690; ---------------------------------------------------------------------------
1691defc PrintFile
1692 if arg( 1) <> '' then
1693 'xcom Save /s /ne' arg( 1) -- Save the file to the printer
1694 endif
1695
1696; ---------------------------------------------------------------------------
1697defc Process_QPrint
1698 universal vEPM_POINTER
1699
1700 if arg( 1) = '' then
1701 'SayError 'PRINTER__MSG /*printername*/ NO_QUEUE__MSG
1702 else
1703 mouse_setpointer WAIT_POINTER
1704 qprint arg( 1)
1705 mouse_setpointer vEPM_POINTER
1706 endif
1707
1708; ---------------------------------------------------------------------------
1709; Flags
1710; F = File
1711; M 1 = marked area (default = entire file)
1712; ! 2 = print immediately; don't wait for print dialog's OK
1713; 4 = queue name given
1714; 8 = PRINTOPTS structure given (binary structure; can't be done via this cmd)
1715; (6.03a or above, only)
1716defc QPrint
1717 parse arg what queue_name
1718 w = wordpos( upcase( what), 'M M! F F! !')
1719 if w then
1720 flags = word( '1 3 0 2 2', w)
1721 else -- Not a flag;
1722 queue_name = arg( 1) -- assume part of the queue name
1723 flags = 0 -- and use default options.
1724 endif
1725 if queue_name <> '' then flags = flags + 4; endif
1726 call windowmessage( 0,
1727 getpminfo(APP_HANDLE),
1728 5144, -- EPM_PRINTDLG
1729 flags,
1730 Put_In_Buffer( queue_name))
1731
1732; ---------------------------------------------------------------------------
1733defc IbmMsg
1734 ever = EVERSION
1735 if \0 = rightstr( EVERSION, 1) then
1736 ever = leftstr( EVERSION, length( eversion) - 1)
1737 endif
1738 call WinMessageBox( EDITOR__MSG,
1739 EDITOR_VER__MSG ver( 0)\13 ||
1740 MACROS_VER__MSG ever\13\13 ||
1741 COPYRIGHT__MSG,
1742 16384)
1743
1744; ---------------------------------------------------------------------------
1745defproc LoadVersionString( var buff, var modname)
1746 hmodule = \0\0\0\0
1747
1748 if arg( 3) then
1749 modname = arg( 3)\0
1750 rc = dynalink32( 'DOSCALLS',
1751 '#318', -- Dos32LoadModule
1752 atol( 0) || -- Buffer address
1753 atol( 0) || -- Buffer length
1754 address( modname) ||
1755 address( hmodule))
1756 endif
1757
1758 buff = copies( \0, 255)
1759 res = dynalink32( 'PMWIN',
1760 '#781', -- Win32LoadString
1761 GethWndC( EPMINFO_HAB) ||
1762 hmodule || -- NULLHANDLE
1763 atol( 65535) || -- IDD_BUILDDATE
1764 atol( length( buff)) ||
1765 address( buff), 2)
1766 buff = leftstr( buff, res)
1767
1768 if arg( 3) then
1769 modname = copies( \0, 260)
1770 call dynalink32( 'DOSCALLS', -- dynamic link library name
1771 '#320', -- DosQueryModuleName
1772 hmodule || -- module handle
1773 atol( length( modname)) || -- Buffer length
1774 address( modname)) -- Module we've loading
1775 call dynalink32( 'DOSCALLS',
1776 '#322', -- Dos32FreeModule
1777 hmodule)
1778 parse value modname with modname \0
1779 endif
1780
1781; ---------------------------------------------------------------------------
1782defc VersionCheck
1783 -- Get EPM.EXE build date
1784 LoadVersionString( buff, modname)
1785 -- Get ETKEnnn.DLL build date
1786 LoadVersionString( buffe, modname, E_DLL)
1787 -- Get ETKRnnn.DLL build date
1788 LoadVersionString( buffr, modname, ERES2_DLL)
1789 -- Get ETKRnnn.DLL build date
1790 LoadVersionString( buffc, modname, ERES_DLL)
1791 /*
1792 -- Get EPMMRI.DLL build date
1793 LoadVersionString( buffm, modname, 'EPMMRI')
1794 */
1795 call WinMessageBox( 'EPM Build',
1796 EDITOR_VER__MSG ver( 0)\13 ||
1797 MACROS_VER__MSG EVERSION\13 ||
1798 '('wheredefc( 'versioncheck')')'\13\13 ||
1799 'EPM.EXE' buff\13 ||
1800 E_DLL'.DLL' buffe\13 ||
1801 ERES2_DLL'.DLL' buffr\13 ||
1802 ERES_DLL'.DLL' buffc\13 ||
1803 /*'EPMMRI.DLL' buffm\13*/\13 ||
1804 COPYRIGHT__MSG,
1805 16384)
1806
1807; ---------------------------------------------------------------------------
1808; Example output to .EPM Build:
1809; Editor version 6.03b
1810; Macros version 6.03b
1811; (F:\APPS\NEPMD\MYEPM\EX\EPM.EX)
1812;
1813; EPM.EXE (C:\OS2\APPS\EPM.EXE)
1814; ETKE603.DLL (F:\APPS\NEPMD\MYEPM\DLL\ETKE603.DLL)
1815; ETKR603.DLL (C:\OS2\APPS\DLL\ETKR603.DLL)
1816; ETKC603.DLL (C:\OS2\APPS\DLL\ETKC603.DLL)
1817defc VersionCheck_File
1818 'xcom e /c /q tempfile'
1819 if rc <> -282 then -- sayerror( 'New file')
1820 'SayError 'ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc)
1821 return
1822 endif
1823 .autosave = 0
1824 .filename = ".EPM Build"
1825 browse_mode = browse() -- query current state
1826 if browse_mode then
1827 call browse( 0)
1828 endif
1829 insertline EDITOR_VER__MSG ver( 0), 1
1830 insertline MACROS_VER__MSG EVERSION, 2
1831 insertline '('wheredefc( 'versioncheck')')', 3
1832 LoadVersionString( buff, modname)
1833 insertline 'EPM.EXE ' buff '('find_epm_exec()')', .last + 1
1834 LoadVersionString( buff, modname, E_DLL)
1835 insertline E_DLL'.DLL' buff '('modname')', .last + 1
1836 LoadVersionString( buff, modname, ERES2_DLL)
1837 insertline ERES2_DLL'.DLL' buff '('modname')', .last + 1
1838 LoadVersionString( buff, modname, ERES_DLL)
1839 insertline ERES_DLL'.DLL' buff '('modname')', .last + 1
1840 /*
1841 LoadVersionString( buff, modname, 'ETKUCMS')
1842 insertline 'ETKUCMS.DLL' buff '('modname')', .last + 1
1843 LoadVersionString( buff, modname, 'EPMMRI')
1844 insertline 'EPMMRI.DLL' buff '('modname')', .last + 1
1845 */
1846 .modify = 0
1847 if browse_mode then
1848 call browse( 1)
1849 endif
1850
1851; ---------------------------------------------------------------------------
1852; Allow other (maybe linked) packages to query the macro version of EPM.E.
1853; Used by NepmdInfo.
1854; Example: 6.03b
1855defproc GetEVersion
1856 return EVERSION
1857
1858; ---------------------------------------------------------------------------
1859; Allow other (maybe linked) packages to query the version of NEPMD.
1860; Used by NepmdInfo.
1861; Example: 1.21
1862defproc GetNepmdVersion
1863 return NEPMD
1864
1865; ---------------------------------------------------------------------------
1866; Returns the ISO date of the EPM loader.
1867; Used by NepmdInfo to compare versions.
1868defproc GetEpmLoaderDate
1869 EpmLoader = NepmdScanEnv( 'NEPMD_LOADEREXECUTABLE')
1870 MDateTime = NepmdQueryPathInfo( EpmLoader, 'MTIME')
1871 parse value MDateTime with MDate MTime
1872 return MDate
1873
1874; ---------------------------------------------------------------------------
1875defproc Find_Epm_Exec
1876 pib = 1234
1877 tid = 1234
1878
1879 call dynalink32( 'DOSCALLS', -- dynamic link library name
1880 '#312', -- ordinal value for DOS32GETINFOBLOCKS
1881 address( tid) ||
1882 address( pib), 2)
1883 return peekz( peek32( ltoa( pib, 10), 12, 4))
1884
1885; ---------------------------------------------------------------------------
1886defc CheckNepmdVersion
1887 parse value DateTime() with CurDate CurTime
1888 KeyPath = '\NEPMD\Var\VersionCheck'
1889 parse value QueryConfigKey( KeyPath'\CheckDateTime') with LastDate LastTime
1890 do once = 1 to 1
1891 fQuery = 0
1892 -- Compare ISO datetimes
1893 DiffDays = DateTimeDiff( LastDate LastTime, CurDate CurTime, 'd')
1894 if DiffDays >= 1 then
1895 fQuery = 1
1896 endif
1897 --dprintf( 'CheckNepmdVersion: fQuery = 'fQuery)
1898
1899 if fQuery then
1900 CheckResult = 1 -- 1 = failure, default value
1901 call WriteConfigKey( KeyPath'\Result', CheckResult)
1902
1903 WgetCmd = ''
1904 do once2 = 1 to 1
1905 Wget = FindTool( 'wget.exe')
1906 if Wget = '' then
1907 call EditNepmdVersionLine( 'wget not found. See tools below')
1908 leave
1909 endif
1910
1911 KeyPathCheckUrl = '\NEPMD\User\VersionCheck\CheckUrl'
1912 CheckUrl = QueryConfigKey( KeyPathCheckUrl)
1913 p1 = lastpos( '/', CheckUrl)
1914 Name = substr( CheckUrl, p1 + 1)
1915
1916 -- Write Url to UrlFile
1917 UrlFile = GetTmpDir()'\nepmd\tmp.url'
1918 call WriteFile( UrlFile, CheckUrl)
1919
1920 TmpFile = GetTmpPath()''Name
1921 EnqTmpFile = EnquoteFileSpec( TmpFile)
1922 if Exist( TmpFile) then
1923 call EraseTemp( TmpFile)
1924 endif
1925
1926 KeyPath = '\NEPMD\User\Tools'
1927 WgetTemplate = QueryConfigKey( KeyPath'\wget\Template')
1928 WgetCall = ExpandTemplate( WgetTemplate,
1929 'uf='UrlFile, 'of='TmpFile)
1930 -- Can't use EpmTemplate here, because date and time are appended
1931 EpmCall = "start epm /r 'postme VersionParseTmpFile "EnqTmpFile CurDate CurTime"'"
1932
1933 -- Single quotes in the calls must be doubled additionally here,
1934 -- because the lines below are surrounded with single quotes themselves.
1935 WgetCall = DoubleCharInStr( "'", WgetCall)
1936 EpmCall = DoubleCharInStr( "'", EpmCall)
1937
1938 -- Create a temp. cmd file that executes wget and EPM with a posted command.
1939 -- That ensures that the EPM command is executed after wget has completed.
1940 CmdFile = GetTmpPath()'getversion.cmd'
1941 if Exist( CmdFile) then
1942 call DeleteFile( CmdFile)
1943 endif
1944 getfileid cmdfid, CmdFile
1945 if cmdfid <> '' then
1946 activatefile cmdfid
1947 .modify = 0
1948 'xcom q'
1949 endif
1950
1951 'xcom e /c 'CmdFile
1952 if rc <> -282 then -- sayerror( 'New file')
1953 'SayError 'ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc)
1954 return
1955 endif
1956 .autosave = 0
1957
1958 insertline "/**/"
1959 insertline "do 1"
1960 insertline " '"WgetCall"'"
1961 --insertline " if rc <> 0 then"
1962 --insertline " leave"
1963 insertline " '"EpmCall"'"
1964 insertline "end"
1965 insertline "'@DEL "CmdFile"'" -- Delete itself
1966 insertline "exit"
1967
1968 'xcom s'
1969 'xcom q'
1970
1971 -- Execute CmdFile
1972 --dprintf( 'CmdFile = 'CmdFile', WgetCall = 'WgetCall)
1973 call EditNepmdVersionLine( 'Checking for new version...')
1974 'postme os2 /c /min 'CmdFile
1975 enddo
1976 else
1977 --call EditNepmdVersionResult()
1978 'postme EditNepmdVersionResult'
1979 endif
1980 enddo
1981 return
1982
1983; ---------------------------------------------------------------------------
1984defc VersionParseTmpFile
1985 do once = 1 to 1
1986 parse arg TmpFile CurDate CurTime
1987 if leftstr( TmpFile, 1) = '"' then
1988 parse arg '"'TmpFile'"' CurDate CurTime
1989 endif
1990 Language = Get_Env( 'NEPMD_LANGUAGE')
1991 if Language = '' then
1992 Language = 'eng'
1993 endif
1994 Version = ''
1995 Date = ''
1996 Url = ''
1997 CheckResult = 1
1998
1999 getfileid tmpfid, TmpFile
2000 if tmpfid <> '' then
2001 activatefile tmpfid
2002 .modify = 0
2003 'xcom q'
2004 endif
2005
2006 'xcom e' EnquoteFileSpec( TmpFile)
2007 if rc then
2008 --dprintf( 'VersionParseTmpFile: leave, rc for "xcom e' TmpFile'" = 'rc)
2009 leave
2010 endif
2011 --dprintf( 'VersionParseTmpFile: loaded file 'TmpFile)
2012
2013 getfileid tmpfid
2014 .visible = 0
2015 .autosave = 0
2016 --dprintf( 'VersionParseTmpFile: tmpfid = 'tmpfid', .last = '.last)
2017
2018 fSectionFound = 0
2019 do i = 1 to .last
2020 ThisLine = strip( textline( i))
2021 --dprintf( 'ThisLine = 'ThisLine)
2022 if leftstr( ThisLine, 1) = ';' then
2023 iterate
2024 endif
2025 parse value ThisLine with '['ThisSection']'
2026 if not fSectionFound then
2027 if ThisSection = Language then
2028 --dprintf( 'ThisSection = Language = 'Language)
2029 fSectionFound = 1
2030 endif
2031 iterate
2032 endif
2033
2034 parse value ThisLine with ThisVar '=' ThisVal
2035 ThisVar = strip( ThisVar)
2036 ThisVal = strip( ThisVal)
2037 if ThisVar = 'Version' then
2038 Version = ThisVal
2039 elseif ThisVar = 'Date' then
2040 Date = ThisVal
2041 elseif ThisVar = 'URL' then
2042 Url = ThisVal
2043 endif
2044 enddo
2045 --dprintf( 'VersionParseTmpFile: Version = 'Version', Date = 'Date', Url = 'Url)
2046
2047 activatefile tmpfid
2048 .modify = 0
2049 'xcom q'
2050 call DeleteFile( TmpFile)
2051
2052 KeyPath = '\NEPMD\Var\VersionCheck'
2053
2054 -- Save as last check data to ini
2055 call WriteConfigKey( KeyPath'\Version', Version)
2056 call WriteConfigKey( KeyPath'\ReleaseDate', Date)
2057 call WriteConfigKey( KeyPath'\Url', Url)
2058
2059 -- Save current date as last check date
2060 call WriteConfigKey( KeyPath'\CheckDateTime', CurDate CurTime)
2061
2062 if Version = '' then
2063 elseif Date = '' then
2064 elseif Url = '' then
2065 else
2066 -- Change CheckResult to 0 (success)
2067 CheckResult = 0
2068 endif
2069 call WriteConfigKey( KeyPath'\Result', CheckResult)
2070
2071 --call EditNepmdVersionResult()
2072 'postme EditNepmdVersionResult'
2073 enddo
2074
2075; ---------------------------------------------------------------------------
2076; Called by CheckNepmdVersion and by VersionParseTmpFile.
2077defc EditNepmdVersionResult
2078 do once = 1 to 1
2079 KeyPath = '\NEPMD\Var\VersionCheck'
2080 CheckResult = QueryConfigKey( KeyPath'\Result')
2081 Version = QueryConfigKey( KeyPath'\Version')
2082 ReleaseDate = QueryConfigKey( KeyPath'\ReleaseDate')
2083 Url = QueryConfigKey( KeyPath'\Url')
2084 CheckDateTime = QueryConfigKey( KeyPath'\CheckDateTime')
2085 EpmLoaderDate = GetEpmLoaderDate()
2086
2087 KeyPathCheckUrl = '\NEPMD\User\VersionCheck\CheckUrl'
2088 CheckUrl = QueryConfigKey( KeyPathCheckUrl)
2089 --dprintf( 'EditNepmdVersionResult: CheckResult = 'CheckResult', Version = 'Version', NepmdVersion = 'GetNepmdVersion())
2090 --dprintf( ' ReleaseDate = 'ReleaseDate', CheckDateTime = 'CheckDateTime', EpmLoaderDate = 'EpmLoaderDate)
2091
2092 CheckedOn = '(checked on 'CheckDateTime')'
2093 if CheckResult <> 0 then
2094 Text = 'Connection failed: 'CheckUrl CheckedOn
2095 elseif Url = '' then
2096 Text = 'Check failed, URL is missing'
2097 else
2098 fNewVersion = 0
2099 if Version < GetNepmdVersion() then
2100 fNewVersion = 0
2101 elseif Version > GetNepmdVersion() then
2102 fNewVersion = 1
2103 elseif IsoDateToBaseDate( ReleaseDate) > IsoDateToBaseDate( EpmLoaderDate) then
2104 fNewVersion = 1
2105 endif
2106
2107 if fNewVersion then
2108 Text = 'New version 'Version': 'Url CheckedOn
2109 else
2110 Text = 'This is the latest version' CheckedOn
2111 endif
2112 endif
2113
2114 call EditNepmdVersionLine( Text)
2115 enddo
2116 return
2117
2118; ---------------------------------------------------------------------------
2119; Called by CheckNepmdVersion and EditNepmdVersionResult.
2120defproc EditNepmdVersionLine
2121 Text = arg( 1)
2122 InfoFilename = '.NEPMD_INFO'
2123 SearchStr = 'NEPMD version:'
2124 do once = 1 to 1
2125 getfileid InfoFid, InfoFilename
2126 if InfoFid = '' then
2127 'NepmdInfo NOCHECK'
2128 else
2129 activatefile InfoFid
2130 endif
2131 do l = 1 to .last
2132 LineStr = textline( l)
2133 StrippedLineStr = strip( LineStr)
2134 if leftstr( StrippedLineStr, length( SearchStr)) = SearchStr then
2135 --dprintf( l': StrippedLineStr = 'StrippedLineStr)
2136 parse value LineStr with StartStr(SearchStr)RestStr' - '
2137 NewLineStr = StartStr''SearchStr''RestStr' - 'Text
2138 --dprintf( l': NewLineStr = 'NewLineStr)
2139 replaceline NewLineStr, l
2140 .modify = 0
2141 .line = l
2142 leave
2143 endif
2144 enddo
2145 enddo
2146 return
2147
2148; ---------------------------------------------------------------------------
2149;compile if defined( BLOCK_ALT_KEY)
2150defc Beep
2151 a = arg( 1)
2152 do while a <> ''
2153 parse value a with pitch duration a
2154 call Beep( pitch, duration)
2155 enddo
2156;compile endif
2157
2158; ---------------------------------------------------------------------------
2159defc Maybe_Reflow_All
2160 do i = 1 to .last
2161 if textline( i) <> '' then -- Ask only if there's text in the file.
2162 if AskYesNo( REFLOW_ALL__MSG, 1) = YES_CHAR then
2163 'Reflow_All'
2164 endif
2165 leave
2166 endif
2167 enddo
2168
2169; ---------------------------------------------------------------------------
2170; Send EPM window a help message
2171; Arg = help panel #, 9100,... (see MENUHELP.H)
2172; 10 = Help index
2173; 4000 = General help
2174; 0 or * = Using help
2175; 1000 = Keys help
2176; 2000 = Commands help
2177; -1 or unknown = TOC only, better use General help
2178defc HelpPanel, HelpMenu
2179 call windowmessage( 0,
2180 getpminfo( APP_HANDLE),
2181 5133, -- EPM_HelpMgrPanel
2182 arg( 1), -- mp1
2183 0) -- mp2 = NULL
2184
2185; ---------------------------------------------------------------------------
2186; Add a .hlp file to EPM.HLP for the help manager. The specified file is not
2187; added, if it was already added before.
2188; This is also required by menu items, independent from
2189; INCLUDE_WORKFRAME_SUPPORT.
2190; Moved from BOOKMARK.E: defc compiler_help_add.
2191; Opening a help panel of an added .hlp file doesn't work for menu items.
2192; Maybe there is EPM.HLP hardcoded. defc HelpPanel can be used instead.
2193defc AddToHelp, compiler_help_add
2194 universal CurrentHLPFiles
2195
2196 do once = 1 to 1
2197 rest = arg( 1)
2198 AddHlpFiles = ''
2199 do while rest <> ''
2200 rest = strip( rest)
2201 -- Parse at double quotes or at words
2202 ch = leftstr( rest, 1, 1)
2203 if ch = '"' then
2204 parse value rest with '"'next'"' rest
2205 else
2206 parse value rest with next rest
2207 endif
2208 -- Add double quotes, if required
2209 HlpFile = EnquoteFilespec( next)
2210 -- Append to AddHlpFiles if not present
2211 if not pos( upcase( ' 'HlpFile' '), upcase( ' 'CurrentHLPFiles' ')) then
2212 if AddHlpFiles = '' then
2213 AddHlpFiles = HlpFile
2214 else
2215 AddHlpFiles = AddHlpFiles HlpFile
2216 endif
2217 endif
2218 enddo
2219 if AddHlpFiles = '' then
2220 leave
2221 endif
2222
2223 hwndHelpInst = windowmessage( 1,
2224 getpminfo( APP_HANDLE),
2225 5429, -- EPM_Edit_Query_Help_Instance
2226 0,
2227 0)
2228 if hwndHelpInst == 0 then
2229 -- There isn't a help instance deal with
2230 'SayError 'NO_HELP_INSTANCE__MSG'.'
2231 return
2232 endif
2233
2234 newlistZ = CurrentHLPFiles AddHlpFiles\0
2235 retval = windowmessage( 1,
2236 hwndHelpInst,
2237 557, -- HM_SET_HELP_LIBRARY_NAME
2238 ltoa( offset( newlistZ) || selector( newlistZ), 10),
2239 0)
2240 if retval then
2241 'SayError 'ERROR__MSG retval ERROR_ADDING_HELP__MSG AddHlpFiles'.'
2242 -- Revert to the previous version of the HLP list
2243 newlistZ = CurrentHLPFiles\0
2244 retval2 = windowmessage( 1,
2245 hwndHelpInst,
2246 557, -- HM_SET_HELP_LIBRARY_NAME
2247 ltoa( offset( newlistZ) || selector( newlistZ), 10),
2248 0)
2249 if retval2 then
2250 'SayError 'ERROR__MSG retval ERROR_REVERTING__MSG CurrentHLPFiles'.'
2251 endif
2252 return
2253 else
2254 -- OK, extend universal
2255 CurrentHLPFiles = CurrentHLPFiles AddHlpFiles
2256 endif
2257 enddo
2258
2259; ---------------------------------------------------------------------------
2260defc QueryHlp, QueryHelpFiles
2261 'SayError Helpfiles = 'QueryCurrentHlpFiles()
2262
2263defproc QueryCurrentHlpFiles()
2264 universal CurrentHLPFiles
2265 return CurrentHLPFiles
2266
2267; ---------------------------------------------------------------------------
2268defc SetHlp, SetHelpFiles
2269 call SetCurrentHlpFiles( arg( 1))
2270 if rc then
2271 'SayError Error: rc = 'rc', Helpfiles = 'QueryCurrentHlpFiles()
2272 else
2273 'SayError Helpfiles = 'QueryCurrentHlpFiles()
2274 endif
2275
2276defproc SetCurrentHlpFiles( newlist)
2277 universal CurrentHLPFiles
2278
2279 rc = 0
2280 hwndHelpInst = windowmessage( 1,
2281 getpminfo( APP_HANDLE),
2282 5429, -- EPM_Edit_Query_Help_Instance
2283 0,
2284 0)
2285 if hwndHelpInst == 0 then
2286 -- There isn't a help instance deal with
2287 rc = 13
2288 'SayError Error: EPM_Edit_Query_Help_Instance returned no help instance.'
2289 return
2290 endif
2291
2292 newlistZ = newlist\0
2293 retval = windowmessage( 1,
2294 hwndHelpInst,
2295 557, -- HM_SET_HELP_LIBRARY_NAME
2296 ltoa( offset( newlistZ)''selector( newlistZ), 10),
2297 0)
2298 if retval == 0 then
2299 -- It worked, now remember what you told it
2300 CurrentHLPFiles = newlist
2301 return
2302 else
2303 -- Failed for some reason. Anyway, we had better revert to
2304 -- the previous version of the HLP list.
2305 if CurrentHLPFiles == '' then
2306 CurrentHLPFiles = ' '
2307 endif
2308 newlistZ = CurrentHLPFiles\0
2309 retval2 = windowmessage( 1,
2310 hwndHelpInst,
2311 557, -- HM_SET_HELP_LIBRARY_NAME
2312 ltoa( offset( newlistZ)''selector( newlistZ), 10),
2313 0)
2314 if retval2 == 0 then
2315 -- We were able to revert to the old list
2316 rc = retval
2317 'SayError Error: HM_SET_HELP_LIBRARY_NAME returned rc = 'retval'.'
2318 return
2319 else
2320 rc = retval2
2321 'SayError Errors: HM_SET_HELP_LIBRARY_NAME returned rc = 'retval' and 'retval2'.'
2322 return
2323 endif
2324 endif
2325
2326; ---------------------------------------------------------------------------
2327; Internally called when a color or a font is dropped on a window.
2328; This is always followed by a SaveFont or SaveColor command. The internally
2329; defined SaveColor command will be ignored, because its standard args EDIT,
2330; MSG or STAT are not precise enough. Therefore SaveColor is executed from
2331; here additionally.
2332defc SetPresParam
2333 universal msgfont
2334 universal statfont
2335 universal vmessagecolor
2336 universal vstatuscolor
2337 universal vmodifiedstatuscolor
2338 universal vreadonlystatuscolor
2339 universal vdesktopcolor
2340 fModified = (.modify > 0)
2341 --dprintf( 'SETPRESPARAM', 'arg( 1) = ['arg( 1)']')
2342 -- SETPRESPARAM: arg( 1) = [MSGBGCOLOR hwnd=-2147483054 x=175 y=12 rgb=16777215 clrattr=15 oldfgattr=3 oldbgattr=7]
2343 -- SETPRESPARAM: arg( 1) = [MSGFONTSIZENAME hwnd=-2147483054 x=41 y=8 string=10.Helv]
2344 -- SETPRESPARAM: arg( 1) = [STATFONTSIZENAME hwnd=-2147483058 x=636 y=9 string=10.System Proportional Non-ISO]
2345 -- SETPRESPARAM: arg( 1) = [EDITFONTSIZENAME hwnd=-2147483047 x=676 y=179 string=12.System VIO]
2346 parse value arg( 1) with whichctrl ' hwnd='hwnd ' x='x 'y='y rest
2347
2348 -- Font: statusbar, messagebar
2349 if (whichctrl == 'STATFONTSIZENAME') or (whichctrl == 'MSGFONTSIZENAME') then
2350 parse value rest with 'string='psize'.'facename'.'attr
2351 -- psize is pointsize, facename is facename, attr is 'Bold' etc
2352 'SetStatFace' hwnd facename
2353 'SetStatPtSize' hwnd psize
2354 newfont = substr( rest, 8)
2355 if leftstr( whichctrl, 1) = 'S' then -- 'STATFONTSIZENAME'
2356 statfont = newfont
2357 else -- 'MSGFONTSIZENAME'
2358 msgfont = newfont
2359 'SayError 'MESSAGELINE_FONT__MSG
2360 endif
2361
2362 -- Foreground color: statusbar, messagebar
2363 elseif (whichctrl == 'STATFGCOLOR') or (whichctrl == 'MSGFGCOLOR') then
2364 parse value rest with 'rgb='rgb 'clrattr='clrattr 'oldfgattr='oldfgattr 'oldbgattr='oldbgattr
2365 call windowmessage( 0,
2366 hwnd,
2367 4099, -- STATWNDM_SETCOLOR
2368 clrattr,
2369 oldbgattr)
2370 newcolor = clrattr + 16 * oldbgattr
2371 if leftstr( whichctrl, 1) = 'M' then
2372 'SayError 'MESSAGELINE_FGCOLOR__MSG
2373 --dprintf( 'SETPRESPARAM', 'MsgFgColor')
2374 vmessagecolor = newcolor
2375 'SaveColor MESSAGE'
2376 elseif not fModified then
2377 if .readonly then
2378 --dprintf( 'SETPRESPARAM', 'StatFgColor, readonly')
2379 vreadonlystatuscolor = newcolor
2380 'SaveColor READONLYSTATUS'
2381 else
2382 --dprintf( 'SETPRESPARAM', 'StatFgColor, normal')
2383 vstatuscolor = newcolor
2384 'SaveColor STATUS'
2385 endif
2386 else
2387 --dprintf( 'SETPRESPARAM', 'StatFgColor, modified')
2388 vmodifiedstatuscolor = newcolor
2389 'SaveColor MODIFIEDSTATUS'
2390 endif
2391
2392 -- Background color: statusbar, messagebar
2393 elseif (whichctrl == 'STATBGCOLOR') or (whichctrl == 'MSGBGCOLOR') then
2394 parse value rest with 'rgb='rgb 'clrattr='clrattr 'oldfgattr='oldfgattr 'oldbgattr='oldbgattr
2395 call windowmessage( 0,
2396 hwnd,
2397 4099, -- STATWNDM_SETCOLOR
2398 oldfgattr,
2399 clrattr)
2400 newcolor = oldfgattr + clrattr * 16
2401 if leftstr( whichctrl, 1) = 'M' then
2402 'SayError 'MESSAGELINE_BGCOLOR__MSG
2403 --dprintf( 'SETPRESPARAM', 'MsgBgColor')
2404 vmessagecolor = newcolor
2405 'SaveColor MESSAGE'
2406 elseif not fModified then
2407 if .readonly then
2408 --dprintf( 'SETPRESPARAM', 'StatBgColor, readonly')
2409 vreadonlystatuscolor = newcolor
2410 'SaveColor READONLYSTATUS'
2411 else
2412 --dprintf( 'SETPRESPARAM', 'StatBgColor, normal')
2413 vstatuscolor = newcolor
2414 'SaveColor STATUS'
2415 endif
2416 else
2417 --dprintf( 'SETPRESPARAM', 'StatBgColor, modified')
2418 vmodifiedstatuscolor = newcolor
2419 'SaveColor MODIFIEDSTATUS'
2420 endif
2421
2422 -- Background color: editwindow
2423 elseif (whichctrl == 'EDITBGCOLOR') then
2424 parse value rest with 'rgb='rgb 'clrattr='clrattr 'oldfgattr='oldfgattr 'oldbgattr='oldbgattr
2425 map_point 5, x, y, off, comment -- 5 = Win2LCO
2426 line = x
2427 col = y
2428 if line < 1 | col > .last then
2429 --dprintf( 'SETPRESPARAM', 'EditBgColor, background')
2430 vdesktopcolor = clrattr
2431 call windowmessage( 0,
2432 getpminfo( EPMINFO_EDITCLIENT),
2433 5497,
2434 clrattr,
2435 0)
2436 'SaveColor BACKGROUND'
2437 else
2438 if InMark( line, col) then
2439 --dprintf( 'SETPRESPARAM', 'EditBgColor, text, in mark')
2440 .markcolor = (.markcolor // 16) + 16 * clrattr
2441 'SaveColor MARK'
2442 else
2443 --dprintf( 'SETPRESPARAM', 'EditBgColor, text, not in mark')
2444 .textcolor = (.textcolor // 16) + 16 * clrattr
2445 'SaveColor TEXT'
2446 endif
2447 endif
2448
2449 -- Foreground color: editwindow
2450 elseif (whichctrl == 'EDITFGCOLOR') then
2451 parse value rest with 'rgb='rgb 'clrattr='clrattr 'oldfgattr='oldfgattr 'oldbgattr='oldbgattr
2452 map_point 5, x, y, off, comment -- 5 = Win2LCO
2453 line = x
2454 col = y
2455 if InMark( line, col) then
2456 --dprintf( 'SETPRESPARAM', 'EditFgColor, text, in mark')
2457 .markcolor = .markcolor - (.markcolor // 16) + clrattr
2458 'SaveColor MARK'
2459 else
2460 --dprintf( 'SETPRESPARAM', 'EditFgColor, text, not in mark')
2461 .textcolor = .textcolor - (.textcolor // 16) + clrattr
2462 'SaveColor TEXT'
2463 endif
2464
2465 -- Font: editwindow
2466 elseif whichctrl == 'EDITFONTSIZENAME' then
2467 parse value rest with 'string='psize'.'facename'.'attr
2468 -- psize is pointsize, facename is facename, attr is 'Bold' etc
2469 fontsel = 0
2470 do while attr <> ''
2471 parse value attr with thisattr '.' attr
2472 if thisattr = 'Italic' then fontsel = fontsel + 1
2473 elseif thisattr = 'Underscore' then fontsel = fontsel + 2
2474 elseif thisattr = 'Outline' then fontsel = fontsel + 8
2475 elseif thisattr = 'Strikeout' then fontsel = fontsel + 16
2476 elseif thisattr = 'Bold' then fontsel = fontsel + 32
2477 endif
2478 enddo
2479 .font = registerfont( facename, psize, fontsel)
2480 else
2481 'SayError 'UNKNOWN_PRESPARAM__MSG whichctrl
2482 return
2483 endif
2484 --'SayError Set presparm with 'hwnd' as the window 'arg( 1)
2485
2486; ---------------------------------------------------------------------------
2487; Called by SetPresParam for message- or statusbar fontname.
2488defc SetStatFace
2489 parse value arg( 1) with hwnd face
2490 return windowmessage( 0,
2491 hwnd /*getpminfo( EPMINFO_EDITFRAME)*/, -- Post message to edit client
2492 4104, -- STATWNDM_PREFFONTFACE
2493 Put_In_Buffer( face),
2494 1) -- COMMAND_FREESEL
2495
2496; ---------------------------------------------------------------------------
2497; Called by SetPresParam for message- or statusbar fontsize.
2498defc SetStatPtSize
2499 parse value arg( 1) with hwnd ptsize
2500 if leftstr( ptsize, 1) = 'D' then -- Decipoints
2501 parse value ptsize with 'DD' ptsize 'HH'
2502 parse value ptsize with ptsize 'WW'
2503 ptsize = ptsize % 10 -- convert decipoints to points
2504 endif
2505 return windowmessage( 0,
2506 hwnd /*getpminfo( EPMINFO_EDITFRAME)*/, -- Post message to edit client
2507 4106, -- STATWNDM_PREFFONTPTSIZE
2508 ptsize,
2509 0)
2510
2511; ---------------------------------------------------------------------------
2512; Syntax:
2513; Font = Convert2EFont( <size>.<name>[[[.<attrib1>[ <attrib2>]].fgcolor].bgcolor])
2514; or
2515; Font = Convert2EFont( <name>.<size>[[[.<attrib[ <attrib2>]].fgcolor].bgcolor])
2516; Both font specs are valid: '12.System VIO' or 'System VIO.DD120HH16WW8BB'
2517; + or <space> are allowed as separator for <attribs>. <attribs> can be
2518; specified as number or as name.
2519; Different from SetTextColor and SetMarkColor, the appended values for
2520; colors must be separated by a period and go both from 0 to 15.
2521; The returned syntax is used as arg for ProcessFontRequest and could be used
2522; for style settings.
2523; Notes: registerfont uses a different syntax: <name>.<DDsize>.<attrib_num>
2524; fgcol'.'bgcol for e.g. .textcolor can be converted with
2525; trunc( .textcolor//16)'.'.textcolor%16
2526defproc ConvertToEFont
2527 --dprintf( 'CONVERTTOEFONT', 'arg( 1) = 'arg( 1))
2528 parse arg name '.' size '.' rest
2529
2530 next = upcase( size)
2531 next = translate( next, '', 'XDHWB', '0')
2532 if not IsNum( next) then
2533 --'Sayerror size = "'size'" is num, arg( 1) = 'arg( 1)
2534 -- toggle name and size
2535 parse arg size '.' name '.'
2536 endif
2537 --'SayError name = "'name'", size = "'size'", next = "'next'", arg( 1) = 'arg( 1)
2538 parse value upcase( size) with h 'X' w
2539 if h <> '' & w <> '' then
2540 size = 'HH'h'WW'w
2541 endif
2542
2543 attrib = 0
2544 fIsColor = 0
2545 fgcol = 0
2546 bgcol = 0
2547 do while rest <> ''
2548
2549 if fIsColor then
2550 --dprintf( 'CONVERTTOEFONT', 'colors = 'rest)
2551 parse value rest with fgcol '.' bgcol
2552
2553 if fgcol = '' then
2554 elseif not IsNum( fgcol) then
2555 fgcol = ColorNameToNum( fgcol)
2556 if rc then
2557 fgcol = ''
2558 endif
2559 endif
2560
2561 if bgcol = '' then
2562 elseif not IsNum( bgcol) then
2563 bgcol = ColorNameToNum( bgcol)
2564 if rc then
2565 bgcol = ''
2566 endif
2567 endif
2568
2569 if (not IsNum( fgcol)) | (not IsNum( bgcol)) then
2570 fIsColor = 0 -- don't append font segments on error
2571 endif
2572 leave
2573
2574 else
2575 parse value rest with segment '.' rest
2576 attriblist = translate( segment, ' ', '+') -- allow '+' as separator
2577 --dprintf( 'CONVERTTOEFONT', 'attriblist = 'attriblist)
2578
2579 do a = 1 to words( attriblist)
2580 next = word( attriblist, a)
2581 if IsNum( next) then
2582 attrib = attrib + next
2583 elseif next = 'Normal' then
2584 -- attrib = attrib + 0
2585 elseif next = 'Italic' then
2586 attrib = attrib + 1
2587 elseif next = 'Underscore' then
2588 attrib = attrib + 2
2589 elseif next = 'Outline' then
2590 attrib = attrib + 8
2591 elseif next = 'Strikeout' then
2592 attrib = attrib + 16
2593 elseif next = 'Bold' then
2594 attrib = attrib + 32
2595 endif
2596 enddo
2597
2598 -- Check following segment for another attribut name
2599 parse value rest with test '.' junk
2600 if test = '' then
2601 leave
2602 elseif wordpos( test, 'Normal Italic Underscore Strikeout Bold') then
2603 else
2604 fIsColor = 1 -- try to resolve the following segments as colors
2605 --dprintf( 'CONVERTTOEFONT', 'test = 'test', fIsColor = 'fIsColor)
2606 endif
2607 iterate
2608
2609 endif
2610 enddo
2611
2612 if fIsColor then
2613 EFont = name'.'size'.'attrib'.'fgcol'.'bgcol
2614 else
2615 EFont = name'.'size'.'attrib
2616 endif
2617 --dprintf( 'CONVERTTOEFONT', 'EFont = 'EFont)
2618 return EFont
2619
2620; ---------------------------------------------------------------------------
2621defproc ConvertToOs2Font
2622 --dprintf( 'CONVERTTOOS2FONT', 'arg( 1) = 'arg( 1))
2623 parse arg name'.'size'.'attriblist
2624
2625 next = upcase( size)
2626 next = translate( next, '', 'XDHWB', '0')
2627 if not IsNum( next) then
2628 -- toggle name and size
2629 parse arg size'.'name'.'
2630 endif
2631 if leftstr( size, 1) = 'D' then -- Decipoints
2632 parse value size with 'DD' size 'HH'
2633 parse value size with size 'WW'
2634 size = size % 10 -- convert decipoints to points
2635 endif
2636
2637 if attriblist = 0 then
2638 attriblist = ''
2639 endif
2640 if attriblist <> '' then
2641 attriblist = upcase( attriblist)
2642 attriblist = translate( attriblist, ' ', '+.') -- allow '+' or '.' as separator
2643 attrib = 0
2644 do a = 1 to words( attriblist)
2645 next = word( attriblist, a)
2646 if IsNum( next) then
2647 attrib = attrib + next
2648 else
2649 if next = 'NORMAL' then
2650 -- attrib = attrib + 0
2651 elseif wordpos( next, 'ITALIC OBLIQUE SLANTED') then
2652 attrib = attrib + 1
2653 elseif next = 'UNDERSCORE' then
2654 attrib = attrib + 2
2655 elseif next = 'OUTLINE' then
2656 attrib = attrib + 8
2657 elseif next = 'STRIKEOUT' then
2658 attrib = attrib + 16
2659 elseif next = 'BOLD' then
2660 attrib = attrib + 32
2661 endif
2662 endif
2663 enddo
2664
2665 attriblist = ''
2666 rest = attrib
2667 next = rest - 32
2668 if next >= 0 then
2669 attriblist = attriblist'.Bold'
2670 rest = next
2671 endif
2672 next = rest - 16
2673 if next >= 0 then
2674 attriblist = attriblist'.Strikeout'
2675 rest = next
2676 endif
2677 next = rest - 8
2678 if next >= 0 then
2679 attriblist = attriblist'.Outline'
2680 rest = next
2681 endif
2682 next = rest - 2
2683 if next >= 0 then
2684 attriblist = attriblist'.Underscore'
2685 rest = next
2686 endif
2687 next = rest - 1
2688 if next >= 0 then
2689 attriblist = attriblist'.Italic'
2690 rest = next
2691 endif
2692
2693 endif
2694 Os2Font = size'.'name''attriblist
2695 --dprintf( 'CONVERTTOOS2FONT', 'Os2Font = 'Os2Font)
2696 return Os2Font
2697
2698; ---------------------------------------------------------------------------
2699defc ShowFont
2700 universal default_font
2701 universal statfont
2702 universal msgfont
2703
2704 FontId = ''
2705 -- The next 3 specs are equivalent:
2706 --FontId = registerfont( 'System VIO', 'WW8HH16', 0)
2707 --FontId = registerfont( 'System VIO', 'DD12', 0)
2708 FontId = registerfont( 'System VIO', '12', 0)
2709 -- registerfont handles all variants as new fonts and assigns the next
2710 -- font id to it. For a non-existing font, it returns 0.
2711 -- For a non-existing font id, queryfont always returns the spec of
2712 -- font id 1.
2713
2714 dprintf( 'FontId = 'FontId' = 'queryfont( FontId)', default_font = 'default_font' = 'queryfont( default_font)', .font = '.font' = 'queryfont( .font))
2715 dprintf( '0 = 'queryfont( 0)', 1 = 'queryfont( 1)', 2 = 'queryfont( 2)', 3 = 'queryfont( 3))
2716 dprintf( '1 = 'queryfont( 1)' = 'ConvertToOs2Font( queryfont( 1))', 2 = 'queryfont( 2)' = 'ConvertToOs2Font( queryfont( 2)))
2717 dprintf( 'statfont = 'statfont', msgfont = 'msgfont)
2718
2719 -- > FontId = 2 = System VIO.DD120WW0HH0BB.0, default_font = 2 = System VIO.DD120WW0HH0BB.0, .font = 2 = System VIO.DD120WW0HH0BB.0
2720 -- > 0 = WarpSans.DD90WW0HH0BB.0, 1 = WarpSans.DD90WW0HH0BB.0, 2 = System VIO.DD120WW0HH0BB.0, 3 = WarpSans.DD90WW0HH0BB.0
2721 -- > 1 = WarpSans.DD90WW0HH0BB.0 = 9.WarpSans, 2 = System VIO.DD120WW0HH0BB.0 = 12.System VIO
2722 -- > statfont = 10.System Proportional Non-ISO, msgfont = 10.Helv
2723
2724; ---------------------------------------------------------------------------
2725; This works even for fonts that don't exist in the next size.
2726; 8.Helv and Midori Sans have the problem that after MinSize = 2 is reached,
2727; no further change is possible. An unknown E statement causes the error msg
2728; 'Divide by zero'. Then drop a font from the color palette onto the edit
2729; window and restart EPM.
2730; After scrolling to the text font sizes of a dropped font, and after
2731; several dropped fonts, the try to change the font again may not work
2732; anymore and 9.WarpSans is applied instead. It seems as if E runs out of
2733; font ids. After an EPM restart, it starts to work again.
2734defc NextFontSize
2735 universal default_font
2736
2737 do once = 1 to 1
2738
2739 -- Several fonts have the problem that after MinSize = 2 is applied,
2740 -- any further change causes 'Divide by zero'.
2741 MinSize = 3
2742 MaxSize = 18
2743 Direction = arg( 1)
2744 if Direction = '' then
2745 Direction = '+'
2746 else
2747 Direction = upcase( leftstr( Direction, 1))
2748 if pos( Direction, '-PB') then
2749 Direction = '-'
2750 else
2751 Direction = '+'
2752 endif
2753 endif
2754
2755 ThisFontId = .font
2756 if not ThisFontId then
2757 ThisFontId = default_font
2758 endif
2759 ETextFont = queryfont( ThisFontId)
2760 TextFont = ConvertToOs2Font( ETextFont)
2761 parse value TextFont with TextSize '.' Rest
2762 if not IsNum( TextSize) then
2763 leave
2764 endif
2765
2766 NextTextFont = ''
2767 if Direction = '+' then
2768 if TextSize >= MaxSize then
2769 leave
2770 endif
2771 NextTextSize = TextSize + 1
2772 NextTextFont = NextTextSize'.'Rest
2773 else
2774 if TextSize <= MinSize then
2775 leave
2776 endif
2777 NextTextSize = TextSize - 1
2778 NextTextFont = NextTextSize'.'Rest
2779 endif
2780 --dprintf( '.font = '.font', ETextFont = 'ETextFont', TextFont = 'TextFont', NextTextFont = 'NextTextFont)
2781 if NextTextFont = '' then
2782 leave
2783 endif
2784
2785 parse value ConvertToEFont( NextTextFont) with Name'.'Size'.'Sel
2786 FontId = registerfont( Name, Size, Sel)
2787 if FontId = 0 then
2788 leave
2789 endif
2790
2791 'SayHint Text font: 'NextTextFont
2792 if .font = default_font | not .font then
2793 -- Default font
2794 fApplyToAllFiles = 1
2795 else
2796 -- Special font
2797 fApplyToAllFiles = 0
2798 endif
2799
2800 if fApplyToAllFiles then
2801 -- Apply font to all files in the ring that have the default font
2802 getfileid startfid
2803 display -1
2804
2805 dprintf( 'RINGCMD', 'NextFontSize')
2806 'VSyncCursor'
2807 do i = 1 to filesinring( 1)
2808 if .font = default_font then
2809 .font = FontId
2810 endif
2811 nextfile
2812 getfileid curfid
2813 if curfid = startfid then
2814 leave
2815 endif
2816 enddo -- Loop through all files in ring
2817
2818 activatefile startfid -- Make sure we're back where we started (in case was .HIDDEN)
2819 display 1
2820 default_font = FontId
2821
2822 -- Save font to ini
2823 'SaveFont TEXT'
2824 else
2825 -- Use file setting when a special font was set before
2826 'SetTextFont 'NextTextFont
2827 endif
2828
2829 enddo
2830
2831; ---------------------------------------------------------------------------
2832; Called internally by the config dialog, when a font was changed.
2833; Called internally by the style dialog when a font or color is applied
2834; without applying a registered style.
2835; On dropping a font from the font palette onto the edit window, this cmd is
2836; not executed. That change is made internally. This has the bug that the
2837; font of the popup menu is changed, too. It's restored back to the PM
2838; default menu font on restart of EPM.
2839; This cmd can also be used directly to change the fonts or to add color
2840; attributes to marked text.
2841defc ProcessFontRequest
2842 universal default_font
2843 universal statfont
2844 universal msgfont
2845
2846 parse value arg( 1) with fontname '.' fontsize '.' fontsel '.' fsetfont '.' type '.' fgcol '.' bgcol
2847 --dprintf( 'ProcessFontRequest: fontname = 'fontname', fontsize = 'fontsize', fontsel = 'fontsel', arg( 1) = "'arg( 1)'"')
2848
2849 if type < 2 then
2850 fontid = registerfont( fontname, fontsize, fontsel)
2851 endif
2852
2853 if type = 2 then -- Statusline font
2854 statfont = ConvertToOs2Font( fontsize'.'fontname'.'fontsel)
2855 hwnd = getpminfo( EPMINFO_EDITSTATUSHWND)
2856 'SetStatFace' hwnd fontname
2857 'SetStatPtSize' hwnd fontsize
2858 if fsetfont then
2859 'SaveFont STATUS'
2860 endif
2861
2862 elseif type = 3 then -- Messageline font
2863 msgfont = ConvertToOs2Font( fontsize'.'fontname'.'fontsel)
2864 hwnd = getpminfo( EPMINFO_EDITMSGHWND)
2865 'SetStatFace' hwnd fontname
2866 'SetStatPtSize' hwnd fontsize
2867 if fsetfont then
2868 'SaveFont MESSAGE'
2869 endif
2870
2871 elseif type = 1 then
2872 -- Insert font attribute within marked area only
2873 call ApplyFontColorToMark( fontid, fgcol, bgcol)
2874
2875 else
2876 if not fsetfont then
2877 -- Apply font to current file only
2878 .font = fontid
2879 else
2880 -- Apply font to all files in the ring that have the default font
2881 getfileid startfid
2882 'VSyncCursor'
2883 display -1
2884
2885 dprintf( 'RINGCMD', 'ProcessFontRequest')
2886 do i = 1 to filesinring( 1)
2887 if .font = default_font then
2888 .font = fontid
2889 endif
2890 nextfile
2891 getfileid curfid
2892 if curfid = startfid then
2893 leave
2894 endif
2895 enddo -- Loop through all files in ring
2896
2897 activatefile startfid -- Make sure we're back where we started (in case was .HIDDEN)
2898 display 1
2899 default_font = fontid
2900
2901 -- Save font to ini
2902 'SaveFont TEXT'
2903 endif
2904
2905 endif
2906
2907; ---------------------------------------------------------------------------
2908const
2909compile if not defined( MONOFONT_STRINGS)
2910 MONOFONT_STRINGS = 'MONO VIO FIX COURIER LETTER MINCHO TYPEWRITER'
2911compile endif
2912
2913; ---------------------------------------------------------------------------
2914; This is a hack and should be replaced, because is checks names.
2915defproc IsMonoFont
2916 parse value queryfont( .font) with fontname '.' fontsize '.'
2917
2918 fMonoFont = 0
2919
2920 StringList = upcase( MONOFONT_STRINGS)
2921 Name = upcase( fontname)
2922 -- Ignore MONOTYPE, because it's a brand name
2923 wp = wordpos( 'MONOTYPE', Name)
2924 if wp > 0 then
2925 Name = delword( Name, wp, 1)
2926 endif
2927 do w = 1 to words( StringList)
2928 String = word( StringList, w)
2929 if pos( String, Name) > 0 then
2930 fMonoFont = 1
2931 leave
2932 endif
2933 enddo
2934
2935 if fMonoFont = 0 then
2936 if rightstr( fontsize, 2) = 'BB' then -- Bitmapped font
2937 parse value fontsize with 'DD' decipoints 'WW' width 'HH' height 'BB'
2938 if width & height then -- It's fixed pitch
2939 fMonoFont = 1
2940 endif
2941 endif
2942 endif
2943
2944 return fMonoFont
2945
2946; ---------------------------------------------------------------------------
2947const
2948compile if not defined( STD_MONOFONT)
2949; STD_MONOFONT = SYS_MONOSPACED_SIZE'.System Monospaced'
2950 STD_MONOFONT = '12.System VIO' -- 'DD120HH16WW8BB'
2951compile endif
2952
2953; ---------------------------------------------------------------------------
2954; This is a hack and should be replaced, because is checks names.
2955defc Monofont
2956 universal app_hini
2957
2958 NewFont = ''
2959 getfileid fid
2960 call SetAVar( fid'.monofont', 1)
2961 -- Query Monofont from font styles and always use it, if defined
2962 MonoFontList = 'MonoFont Monofont MONOFONT monofont'
2963 do w = 1 to words( MonoFontList)
2964 Wrd = word( MonoFontList, w)
2965 next = queryprofile( app_hini, 'Style', Wrd) -- case-sensitive
2966 if next <> '' then
2967 -- Strip color attributes
2968 parse value next with name'.'size'.'attrib'.'fgcol'.'bgcol
2969 NewFont = name'.'size'.'attrib
2970 leave
2971 endif
2972 enddo
2973 -- If Monofont style is not defined, take default Monofont, but only
2974 -- if current font is not already a monospaced font.
2975 if NewFont = '' then
2976 if not IsMonofont() then
2977 NewFont = STD_MONOFONT
2978 endif
2979 endif
2980 if NewFont <> '' then
2981 'SetTextFont' NewFont -- SetTextFont is defined in MODEEXEC.E
2982 endif
2983
2984; ---------------------------------------------------------------------------
2985; setfont doesn't work in EPM 6.03b
2986/*
2987ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
2988³ what's it called: setfont ³
2989³ ³
2990³ what does it do : Send change font message to editor. ³
2991³ Arguments are the font cell width and the font cell ³
2992³ height. Example: setfont( 7, 15) ³
2993³ ³
2994³ ³
2995³ who and when : Jerry C. 11/04/89 ³
2996ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
2997*/
2998/*
2999defproc SetFont( width, height)
3000 call windowmessage( 0,
3001 getpminfo( EPMINFO_EDITCLIENT), -- Post message to edit client
3002 5381, -- EPM_EDIT_CHANGEFONT
3003 height,
3004 width)
3005*/
3006
3007; ---------------------------------------------------------------------------
3008const
3009 COLOR_CONVERSION_LIST = '' ||
3010 'BLACK' || '/' || '0' || '/' ||
3011 'BLUE' || '/' || '1' || '/' ||
3012 'GREEN' || '/' || '2' || '/' ||
3013 'CYAN' || '/' || '3' || '/' ||
3014 'RED' || '/' || '4' || '/' ||
3015 'MAGENTA' || '/' || '5' || '/' ||
3016 'BROWN' || '/' || '6' || '/' ||
3017 'LIGHT_GRAY' || '/' || '7' || '/' ||
3018 'DARK_GRAY' || '/' || '8' || '/' ||
3019 'LIGHT_BLUE' || '/' || '9' || '/' ||
3020 'LIGHT_GREEN' || '/' || '10' || '/' ||
3021 'LIGHT_CYAN' || '/' || '11' || '/' ||
3022 'LIGHT_RED' || '/' || '12' || '/' ||
3023 'LIGHT_MAGENTA' || '/' || '13' || '/' ||
3024 'YELLOW' || '/' || '14' || '/' ||
3025 'WHITE' || '/' || '15' || '/'
3026
3027; ---------------------------------------------------------------------------
3028; Syntax: ColorNum = ColorNameToNum( <color1> [+ <color2>])
3029; <colors> are color names or numbers. The resulting Color is the summed
3030; value of all.
3031; Sets rc = 0 if color was resolved, else rc = 1.
3032defproc ColorNameToNum( Args)
3033 rc = 0
3034 ColorNum = 0
3035
3036 do once = 1 to 1
3037 if Args = '' | Args = 'DEFAULT' then
3038 -- Don't return 0 = BLACK
3039 ColorNum = Args
3040 leave
3041 elseif IsNum( Args) then
3042 ColorNum = Args
3043 leave
3044 endif
3045
3046 -- Uppercase
3047 Names = upcase( Args)
3048 -- Remove spaces
3049 Names = RmSpaces( Names)
3050
3051 do while Names <> ''
3052
3053 -- Parse every arg at '+' boundaries
3054 parse value Names with ColorName '+' Names
3055 fFound = 0
3056 fBackground = 0
3057
3058 if IsNum( ColorName) then
3059 ColorNum = ColorNum + ColorName -- add
3060 fFound = 1
3061 iterate
3062 endif
3063
3064 -- Parse trailing 'B'
3065 if rightstr( ColorName, 1) = 'B' then
3066 fBackground = 1
3067 ColorName = leftstr( ColorName, length( ColorName) - 1)
3068 endif
3069
3070 -- Add underscore after 'LIGHT', 'DARK' or 'PALE', if missing
3071 parse value ColorName with 'LIGHT'next
3072 if next <> '' & leftstr( next, 1) <> '_' then
3073 ColorName = 'LIGHT_'next
3074 else
3075 parse value ColorName with 'DARK'next
3076 if next <> '' & leftstr( next, 1) <> '_' then
3077 ColorName = 'DARK_'next
3078 else
3079 parse value ColorName with 'PALE'next
3080 if next <> '' & leftstr( next, 1) <> '_' then
3081 ColorName = 'PALE_'next
3082 endif
3083 endif
3084 endif
3085
3086 -- Change synonyms
3087 ColorName = ChangeStr( 'GREY', ColorName, 'GRAY')
3088 ColorName = ChangeStr( 'PALE_GRAY', ColorName, 'LIGHT_GRAY')
3089 if ColorName = 'GRAY' then
3090 ColorName = 'LIGHT_GRAY'
3091 endif
3092
3093 -- Parse list
3094 rest = COLOR_CONVERSION_LIST
3095 do while rest <> ''
3096 parse value rest with next1'/'next2'/'rest
3097 -- Compare
3098 if ColorName = next1 then
3099 if not fBackground then
3100 ColorNum = ColorNum + next2 -- add foreground color
3101 fFound = 1
3102 leave
3103 else
3104 ColorNum = ColorNum + 16 * next2 -- add background color
3105 fFound = 1
3106 leave
3107 endif
3108 endif
3109 enddo
3110
3111 if fFound = 0 then
3112 rc = 1
3113 'SayError Error: ColorNameToNum: "'ColorName'" is not a color specification.'
3114 leave
3115 endif
3116 enddo
3117
3118 enddo
3119
3120 return ColorNum
3121
3122; ---------------------------------------------------------------------------
3123; Syntax: ColorName = ColorNameToNum( <colornum>)
3124; <colornum> is a color number.
3125; Sets rc = 0 if colornum was resolved, else rc = 1.
3126defproc ColorNumToName( Args)
3127 rc = 0
3128 ColorName = ''
3129 FgColorName = ''
3130 BgColorName = ''
3131
3132 do once = 1 to 1
3133 if not IsNum( Args) then
3134 rc = 1
3135 'SayError Error: ColorNumToName: "'Args'" is not a color number.'
3136 leave
3137 endif
3138
3139 FgColorNum = Args // 16
3140 BgColorNum = Args % 16
3141
3142 do c = 1 to 2
3143 fFound = 0
3144 if c = 1 then
3145 ColorNum = FgColorNum
3146 elseif c = 2 then
3147 ColorNum = BgColorNum
3148 endif
3149
3150 -- Parse list
3151 rest = COLOR_CONVERSION_LIST
3152 do while rest <> ''
3153 parse value rest with next1'/'next2'/'rest
3154 -- Compare
3155 if ColorNum = next2 then
3156 if c = 1 then
3157 FgColorName = next1
3158 elseif c = 2 then
3159 BgColorName = next1
3160 endif
3161 fFound = 1
3162 leave
3163 endif
3164 enddo
3165
3166 if fFound = 0 then
3167 rc = 1
3168 'SayError Error: ColorNumToName: "'ColorNum'" is not a fore- or background color number.'
3169 leave
3170 endif
3171 enddo
3172 if rc then
3173 leave
3174 endif
3175
3176 -- Assemble E color name
3177 ColorName = FgColorName'+'BgColorName'B'
3178 enddo
3179
3180 return ColorName
3181
3182; ---------------------------------------------------------------------------
3183; Opens a listbox to select a color palette. The list of color palettes is
3184; parsed by COLORS.ERX from both NEPMD.INI and existing palette objects.
3185; Uses also COLORS.ERX to patch ETKE603.DLL on applying a color set.
3186defc SelectColorPal
3187
3188 NumItems = 0
3189 ListBoxData = ''
3190 Next = RxResult( 'colors.erx L')
3191 if Next <> '' then
3192 -- Get number of items
3193 Sep = leftstr( Next, 1)
3194 Check = translate( translate( Next, '_', ' '), ' ', Sep)
3195 NumItems = words( Check)
3196 ListBoxData = Next
3197 endif
3198
3199 DefaultItem = 1
3200 DefaultButton = 1
3201 HelpId = 0
3202 Title = 'Change color palette'
3203 Text = 'Select a color palette from the list below:'
3204 Buttons = '/~Set/~Open/~Copy.../~Delete/'CANCEL__MSG
3205
3206 refresh
3207 Result = ListBox( Title,
3208 ListBoxData,
3209 Buttons,
3210 0, 0, --5, 5, -- top, left,
3211 Min( NumItems, 15), 50, -- height, width
3212 GethWndC( APP_HANDLE) ||
3213 atoi( DefaultItem) ||
3214 atoi( DefaultButton) ||
3215 atoi( HelpId) ||
3216 Text)
3217 refresh
3218
3219 -- Parse return string
3220 parse value Result with Button 2 Select \0
3221 Button = asc( Button)
3222
3223 ColorPal = Select
3224 if pos( ' ', ColorPal) then
3225 ColorPal = '"'ColorPal'"'
3226 endif
3227
3228 if Button = 1 then -- Set
3229 rcx = RxResult( 'colors.erx S' ColorPal)
3230 --'SayError RxResult from "rx colors.erx' ColorPal'" = 'rcx
3231 elseif Button = 2 then -- Open
3232 rcx = RxResult( 'colors.erx O' ColorPal)
3233 elseif Button = 3 then -- Copy
3234 'EnterColorPalName' ColorPal
3235 elseif Button = 4 then -- Delete
3236 rcx = RxResult( 'colors.erx D' ColorPal)
3237 'SelectColorPal'
3238 else -- Cancel
3239 -- nop
3240 endif
3241
3242 return
3243
3244; ---------------------------------------------------------------------------
3245defc EnterColorPalName
3246 ColorPal = arg( 1)
3247 if leftstr( ColorPal, 1) == '"' then
3248 parse value ColorPal with '"'ColorPal'"'
3249 endif
3250 Title = 'Copy color palette "'ColorPal'"'
3251 Text = 'Enter a new name:'
3252 OldEntry = ''
3253 Buttons = '/'OK__MSG'/'CANCEL__MSG
3254 DefButton = 1
3255 Title = leftstr( Title, 100)'.' -- Add spaces to fit the text in titlebar
3256 HelpId = 0
3257 ret = EntryBox( Title,
3258 Buttons,
3259 OldEntry,
3260 '',
3261 255, -- Length
3262 atoi( DefButton) || atoi( HelpId) || GethWndC( APP_HANDLE) ||
3263 Text)
3264
3265 -- Parse return string
3266 parse value ret with Button 2 Select \0
3267 Button = asc( Button)
3268
3269 NewEntry = strip( Select)
3270
3271 if Button = 2 | Button = 0 then -- 0 = Esc, 2 = Cancel
3272 'SelectColorPal'
3273 elseif Button = 1 then -- 1 = OK
3274 if ColorPalNameExists( NewEntry) | NewEntry = '' then
3275 'EnterColorPalName' ColorPal -- call this command again
3276 else
3277 -- Handle spaces in name
3278 if pos( ' ', ColorPal) then
3279 ColorPal = '"'ColorPal'"'
3280 endif
3281 if pos( ' ', NewEntry) then
3282 NewEntry = '"'NewEntry'"'
3283 endif
3284 rcx = RxResult( 'colors.erx C' ColorPal NewEntry)
3285 'SelectColorPal'
3286 endif
3287 endif
3288
3289; ---------------------------------------------------------------------------
3290defproc ColorPalNameExists
3291 universal nepmd_hini
3292
3293 PalName = arg( 1)
3294
3295 -- Don't override existing names
3296 KeyPath = '\NEPMD\User\Colors\Highlighting'
3297 fNameExists = 0
3298
3299 -- Compare NewEntry with default names
3300 do NextNum = 101 to 200
3301 if fNameExists then
3302 leave
3303 endif
3304 NextName = QueryConfigKey( KeyPath'\'NextNum'\Name')
3305 if NextName = '' then
3306 leave
3307 endif
3308 if PalName = NextName then
3309 fNameExists = 1
3310 endif
3311 enddo
3312
3313 -- Compare NewEntry with user names
3314 SearchOption = 'C'
3315 NextNum = ''
3316 FoundNum = ''
3317 do while NepmdGetNextConfigKey( nepmd_hini, KeyPath, SearchOption, NextNum)
3318 if fNameExists then
3319 leave
3320 endif
3321 if not IsNum( NextNum) then
3322 iterate
3323 endif
3324 NextName = QueryConfigKey( KeyPath'\'NextNum'\Name')
3325 if NextName = '' then
3326 iterate
3327 endif
3328 if PalName = NextName then
3329 fNameExists = 1
3330 endif
3331 enddo
3332
3333 return fNameExists
3334
3335; ---------------------------------------------------------------------------
3336; Thunk is used for host support only.
3337defproc Thunk( pointer)
3338 return atol_swap( dynalink32( E_DLL,
3339 'FlatToSel',
3340 pointer, 2))
3341
3342; ---------------------------------------------------------------------------
3343defc EchoBack
3344 parse arg postorsend hwnd messageid mp1 mp2 .
3345 call windowmessage( postorsend,
3346 hwnd,
3347 messageid,
3348 mp1,
3349 mp2)
3350
3351; ---------------------------------------------------------------------------
3352defc Dyna_Cmd
3353 parse arg library entrypoint cmdargs
3354 if entrypoint = '' then
3355 'SayError '-257 -- 'Invalid number of parameters'
3356 return
3357 endif
3358 rc = 0
3359 cmdargs = cmdargs\0
3360 rcx = dynalink32( library,
3361 entrypoint,
3362 GethWndC( EPMINFO_EDITCLIENT) ||
3363 address( cmdargs),
3364 2)
3365
3366; ---------------------------------------------------------------------------
3367defc DynaFree
3368 rc = dynafree( arg( 1))
3369 if rc then
3370 'SayError 'ERROR__MSG rc
3371 endif
3372
3373; ---------------------------------------------------------------------------
3374; Stops if current window is not the only EPM window, so this can be used as
3375; command.
3376defc CheckOnlyEpmWindow
3377 Cmd = strip( arg( 1))
3378 if Cmd = '' then
3379 CurCmd = 'The current command'
3380 else
3381 CurCmd = 'The '''Cmd''' command'
3382 endif
3383
3384 do while not IsOnlyEpmWindow()
3385 refresh
3386 Title = 'Multiple EPM windows'
3387 Text = CurCmd' can''t be executed as long as multiple' ||
3388 ' EPM windows are open.'\n\n ||
3389 'Press "OK" to try again or "Cancel" to abort.'
3390 rcx = WinMessageBox( Title, Text,
3391 MB_OKCANCEL + MB_WARNING + MB_MOVEABLE)
3392 if rcx = MBID_OK then
3393 iterate
3394 else
3395 rc = -269 -- User Break. Command halted
3396 stop
3397 endif
3398 enddo
3399
3400; ---------------------------------------------------------------------------
3401; Returns 0 or 1.
3402defproc IsOnlyEpmWindow
3403 ptr = dynalink32( 'PMWIN',
3404 '#839', -- Win32QueryWindowPtr
3405 GethWndC( EPMINFO_OWNERFRAME) ||
3406 atol( 0), 2)
3407 listptr = ltoa( peek32( ptr, 1856, 4), 10)
3408 hwndx = peek32( listptr, 0, 4)
3409 next = ltoa( peek32( listptr, 8, 4), 10)
3410 if not next then
3411 return 1
3412 else
3413 return 0
3414 endif
3415
3416; ---------------------------------------------------------------------------
3417; When a non-temporary file (except .Untitled) in ring is modified, then
3418; - make this file topmost
3419; - give a message
3420; - set rc = 1 (but not required, because stop is used)
3421; - stop processing of calling command or procedure.
3422; Otherwise set rc = 0.
3423defc RingCheckModify
3424 rc = 0
3425 getfileid fid
3426 startfid = fid
3427 dprintf( 'RINGCMD', 'RingCheckModify')
3428 'VSyncCursor'
3429
3430 do i = 1 to filesinring( 1) -- just as an upper limit
3431 -- This ensures that special files can be closed without
3432 -- popping up a message box that asks "Are you sure?"
3433 if FileShouldBeDiscarded() then
3434 'DiscardChanges'
3435 else
3436 rcx = CheckModify()
3437 if rcx then
3438 activatefile startfid
3439 rc = rcx
3440 stop
3441 endif
3442 endif
3443 nextfile
3444 getfileid fid
3445 if fid = startfid then
3446 leave
3447 endif
3448 enddo
3449
3450; ---------------------------------------------------------------------------
3451defc CheckModify
3452 rcx = CheckModify()
3453 if rcx then
3454 stop
3455 endif
3456
3457; ---------------------------------------------------------------------------
3458; Resets .modify for Yes or No button. Yes: Save, No: Discard.
3459defproc CheckModify
3460 rc = 0
3461 if .modify then
3462
3463 refresh
3464 Title = 'Save modified file'
3465 Text = .filename\n\n ||
3466 'The above file is modified. Press "Yes" to save it,' ||
3467 ' "No" to discard it or "Cancel" to abort.'\n\n ||
3468 'Do you want to save it?'
3469 rcx = WinMessageBox( Title, Text,
3470 MB_YESNOCANCEL + MB_QUERY + MB_DEFBUTTON1 + MB_MOVEABLE)
3471
3472 if rcx = MBID_YES then
3473 'Save'
3474 elseif rcx = MBID_NO then
3475 .modify = 0
3476 else
3477 rc = -5
3478 endif
3479 endif
3480 return rc
3481
3482; ---------------------------------------------------------------------------
3483; Some PMWIN.H constants:
3484#define QW_NEXT 0
3485#define QW_PREV 1
3486#define QW_TOP 2
3487#define QW_BOTTOM 3
3488#define QW_OWNER 4
3489#define QW_PARENT 5
3490#define QW_NEXTTOP 6
3491#define QW_PREVTOP 7
3492#define QW_FRAMEOWNER 8
3493
3494#define FID_CLIENT 0x8008
3495
3496#define HWND_DESKTOP 1
3497#define HWND_TOP 3
3498#define HWND_BOTTOM 4
3499
3500#define QWL_STYLE (-2)
3501
3502#define SWP_SIZE 0x0001
3503#define SWP_MOVE 0x0002
3504#define SWP_ZORDER 0x0004
3505#define SWP_ACTIVATE 0x0080
3506#define SWP_RESTORE 0x1000
3507
3508#define WS_MINIMIZED 0x01000000
3509
3510; ---------------------------------------------------------------------------
3511; EPM /m windows are not included. It works with minimized windows. The focus
3512; is set to the next window in the Z-order.
3513defc Next_Win, NextWin
3514 ptr = dynalink32( 'PMWIN',
3515 '#839', -- Win32QueryWindowPtr
3516 GethWndC( EPMINFO_OWNERFRAME) ||
3517 atol( 0), 2)
3518 listptr = ltoa( peek32( ptr, 1856, 4), 10)
3519 hwndx = peek32( listptr, 0, 4)
3520 next = ltoa( peek32( listptr, 8, 4), 10)
3521 if not next then
3522 'SayError This is the only edit window.'
3523 return
3524 endif
3525 first_hwndx = hwndx
3526 my_hwndx = GethWndC( EPMINFO_EDITCLIENT)
3527 do while hwndx /== my_hwndx
3528 listptr = next
3529 hwndx = peek32( listptr, 0, 4)
3530 next = ltoa( peek32( listptr, 8, 4), 10)
3531 enddo
3532 if next then
3533 hwndx = peek32( next, 0, 4)
3534 else
3535 hwndx = first_hwndx
3536 endif
3537 EFrame_hwnd = dynalink32( 'PMWIN',
3538 '#834', -- Win32QueryWindow
3539 hwndx ||
3540 atol( QW_PARENT), 2)
3541
3542 call MakeWindowTopmost( EFrame_hwnd)
3543
3544 -- Give the focus to the edit window of EFrame_hwnd. Otherwise an open
3545 -- search window changes its owner to that topmost window and takes the
3546 -- focus, what is not intended in that case. PostMe is required to
3547 -- process SetFocus as last one.
3548 'PostMe SetFocus' ltoa( hwndx, 10)
3549 -- Highlight the cursor of that window
3550 PostCmdToEditWindow( 'HighlightCursor', ltoa( hwndx, 10))
3551
3552/*
3553; ---------------------------------------------------------------------------
3554; Not really part of next_win, but throw it in anyway...
3555defc ewin = -- List edit windows
3556 call windowmessage( 0,
3557 getpminfo( APP_HANDLE), -- Send message to owner client
3558 32, -- WM_COMMAND - 0x0020
3559 203, -- IDM_EDITWNDS
3560 0)
3561*/
3562
3563
3564/*
3565; ---------------------------------------------------------------------------
3566; Following PMWIN calls switch to the next *topmost* EPM window, not to that
3567; one with the next hwnd.
3568; Bug: hidden windows are not restored.
3569; This includes EPM /m windows, but the focus is toggled between the two
3570; topmost windows.
3571
3572; I am not aware of any EPM commands or procs to help switch the
3573; focus between files in separate edit rings, like godoc in LPEX.
3574; So I wrote this little utility to toggle between EPM windows.
3575; It works by checking all top level frame windows for a client
3576; belonging to the same class as the current EPM window.
3577
3578/*------------------------------------------------+
3579 | EPM macro code to jump to the other edit ring |
3580 | Author: Michael Golding, IBM (STL), 8-543-3569 |
3581 +------------------------------------------------*/
3582; def c_F12 = 'KWIKJMP'
3583
3584include 'stdconst.e'
3585
3586defc kwikjmp
3587 buf = leftstr( '', 128, \0)
3588 desktop = atol( 1) -- (1 == HWND_DESKTOP)
3589 hndFrame = GethWndC( EPMINFO_EDITFRAME)
3590
3591 len = dynalink32( 'PMWIN',
3592 '#805', -- WinQueryClassName
3593 GethWndC( EPMINFO_EDITCLIENT) ||
3594 atol( 128) ||
3595 address( buf), 2)
3596
3597 henum = atol( dynalink32( 'PMWIN',
3598 '#702', -- WinBeginEnumWindows
3599 desktop, 2))
3600
3601 clsname = leftstr( buf, len)
3602 found = 0
3603 cnt = 0
3604 --- examine desktop windows for client of same edit class
3605 do while cnt < 250
3606 cnt = cnt + 1
3607
3608 hnd = dynalink32( 'PMWIN',
3609 '#756', -- WinGetNextWindow
3610 henum, 2)
3611
3612 hndF = atol( hnd)
3613
3614 if not hnd then
3615 leave -- no more top-level windows
3616 elseif hndF = hndFrame then
3617 iterate -- just me, never mind
3618 endif
3619
3620 hnd = dynalink32( 'PMWIN',
3621 '#899', -- WinWindowFromId
3622 hndF ||
3623 atol( 32776), 2) -- get client
3624
3625 len = dynalink32( 'PMWIN',
3626 '#805', -- WinQueryClassName
3627 atol( hnd) ||
3628 atol( 128) ||
3629 address( buf), 2)
3630
3631 if clsname = leftstr( buf, len) then -- same class as me?
3632 found = 1 -- YES!!
3633 leave
3634 endif
3635 enddo
3636
3637 call dynalink32( 'PMWIN',
3638 '#737', -- WinEndEnumWindows
3639 henum, 2)
3640
3641 if found then
3642 call dynalink32( 'PMWIN',
3643 '#851', -- WinSetActiveWindow
3644 desktop ||
3645 atol( hnd), 2)
3646
3647 elseif cnt < 250 then
3648 'SayError *** window not found: cnt='cnt
3649
3650 else
3651 'SayError *** bailed out: cnt='cnt
3652 endif
3653*/
3654
3655; ---------------------------------------------------------------------------
3656defc CloseOtherWin
3657 buf = leftstr( '', 128, \0)
3658 desktop = atol( 1) -- (1 == HWND_DESKTOP)
3659 my_hwndx = GethWndC( EPMINFO_EDITFRAME)
3660 --dprintf( 'CloseOtherWin, '.filename)
3661
3662 -- Get ClsName (NewEditWndClass) of current edit client window
3663 len = dynalink32( 'PMWIN',
3664 '#805', -- WinQueryClassName
3665 GethWndC( EPMINFO_EDITCLIENT) ||
3666 atol( 128) ||
3667 address( buf), 2)
3668 ClsName = leftstr( buf, len)
3669
3670 -- Examine desktop windows for client of same edit class
3671 henum = atol( dynalink32( 'PMWIN',
3672 '#702', -- WinBeginEnumWindows
3673 desktop, 2))
3674 cnt = 0
3675 do while cnt < 250
3676 cnt = cnt + 1
3677
3678 hwnd = dynalink32( 'PMWIN',
3679 '#756', -- WinGetNextWindow
3680 henum, 2)
3681
3682 if not hwnd then
3683 -- No more top-level windows
3684 leave
3685 elseif atol( hwnd) == my_hwndx then
3686 -- Just me, never mind
3687 iterate
3688 endif
3689
3690 hwndClient = dynalink32( 'PMWIN',
3691 '#899', -- WinWindowFromId
3692 atol( hwnd) ||
3693 atol( FID_CLIENT), 2) -- get client
3694
3695 len = dynalink32( 'PMWIN',
3696 '#805', -- WinQueryClassName
3697 atol( hwndClient) ||
3698 atol( 128) ||
3699 address( buf), 2)
3700
3701 -- Same class as me?
3702 if ClsName = leftstr( buf, len) then
3703 --dprintf( 'ClsName = 'ClsName)
3704 -- Make minimized windows topmost first. This is useful if the
3705 -- 'Ask to quit on modified' dialog opens on posting a WM_CLOSE msg.
3706 Style = dynalink32( 'PMWIN',
3707 '#843', -- Win32QueryWindowULong
3708 atol( hwnd) ||
3709 atol( QWL_STYLE), 2)
3710 if Style bitand WS_MINIMIZED then
3711 opts = SWP_ZORDER bitor SWP_ACTIVATE bitor SWP_RESTORE
3712 call dynalink32( 'PMWIN',
3713 '#875', -- Win32SetWindowPos
3714 atol( hwnd) ||
3715 atol( HWND_TOP) ||
3716 atol( 0) ||
3717 atol( 0) ||
3718 atol( 0) ||
3719 atol( 0) ||
3720 atol( opts))
3721 endif
3722
3723 -- Close window
3724 call windowmessage( 0,
3725 hwnd,
3726 41, -- WM_CLOSE
3727 0,
3728 0)
3729 endif
3730 enddo
3731 call dynalink32( 'PMWIN',
3732 '#737', -- WinEndEnumWindows
3733 henum, 2)
3734
3735; ---------------------------------------------------------------------------
3736; Check for a modified file in ring. If not, save all rings and restart all.
3737; Syntax: Restart [Args]
3738defc Restart
3739 universal excludehwndlist
3740
3741 do once = 1 to 1
3742 Args = arg( 1)
3743
3744 if Args = '' then
3745 Cmd = 'RestoreLastRing'
3746 else
3747 Cmd = 'mc ;RestoreLastRing;AfterStartup' Args
3748 endif
3749
3750 excludehwndlist = ''
3751 'SaveLastRing'
3752 'CheckAllRingsModify'
3753 'CloseOtherWin'
3754 excludehwndlist = ''
3755
3756 -- Write flag that last rings have to be restored
3757 KeyPath = '\NEPMD\Var\RestoreLastRing\Done'
3758 WriteConfigKey( KeyPath, 0)
3759
3760 EpmArgs = "'"Cmd"'"
3761compile if 0
3762 -- Doesn't work really reliable everytime (but even though useful):
3763 -- o Sometimes EPM.EX is not reloaded.
3764 -- o Sometimes EPM crashes on 'SaveLastRing' or on executing arg( 1).
3765 -- -> Still happens?
3766 'postme Open' EpmArgs
3767compile else
3768 -- Using external .cmd now:
3769 EpmExe = Get_Env( 'NEPMD_LOADEREXECUTABLE')
3770 'postme start /c /min epmresume' EpmExe EpmArgs
3771 'postme Close'
3772compile endif
3773 enddo
3774
3775; ---------------------------------------------------------------------------
3776; Syntax: hWnd = QueryFocus() or hWnd = QueryFocus( hWndParent)
3777defproc QueryFocus
3778 rc = 1
3779 if arg() = 1 then
3780 hWndParent = arg( 1)
3781 else
3782 hWndParent = 1 -- HWND_DESKTOP
3783 endif
3784 hWnd = dynalink32( 'PMWIN', -- dynamic link library name
3785 '#817', -- Win32QueryFocus
3786 atol( hWndParent), 2)
3787 if hWnd then
3788 rc = 0
3789 endif
3790 return hWnd
3791
3792defc QueryFocus
3793 hWnd = QueryFocus()
3794 dprintf( 'QueryFocus: hWnd = 'hWnd)
3795
3796; ---------------------------------------------------------------------------
3797; Syntax: SetFocus( [hWnd]) or SetFocus( hWndParent, hWnd)
3798defproc SetFocus
3799 if arg() = 2 then
3800 hWndParent = arg( 1)
3801 hWnd = arg( 2)
3802 else
3803 hWnd = arg( 1)
3804 hWndParent = 1 -- HWND_DESKTOP
3805 endif
3806 if hWnd = '' then
3807 hWnd = 1 -- Default is HWND_DESKTOP
3808 endif
3809 rc = 1
3810 rcx = dynalink32( 'PMWIN', -- dynamic link library name
3811 '#860', -- Win32SetFocus
3812 atol( hWndParent) ||
3813 atol( hWnd))
3814 if rcx = 1 then
3815 rc = 0
3816 endif
3817 return
3818
3819defc SetFocus
3820 call SetFocus( arg( 1))
3821
3822; ---------------------------------------------------------------------------
3823defc SetFocusToThisWindow
3824 hWndFrame = getpminfo( EPMINFO_EDITFRAME)
3825 hWndClient = getpminfo( EPMINFO_EDITCLIENT)
3826 -- Clicks with MB 1:
3827 -- Using the cmd 'SetFocus' here seems to work more stable than the proc
3828 -- 'SetFocus'. A cmd is executed somehow delayed. Usually in this case,
3829 -- PostMe is used. But the entire cmd 'SetFocusToThisWindow' is already
3830 -- posted in MH_SingleClick. If it's still not stable enough, use PostMe
3831 -- also for SetFocus:
3832 'PostMe MakeWindowTopmost' hWndFrame
3833 'PostMe SetFocus' hWndClient
3834
3835; ---------------------------------------------------------------------------
3836defc SetFocusToEditClient
3837 hWndClient = getpminfo( EPMINFO_EDITCLIENT)
3838 'SetFocus' hWndClient
3839
3840; ---------------------------------------------------------------------------
3841defproc QueryParent
3842 hWnd = arg( 1)
3843 hwndFrame = dynalink32( 'PMWIN',
3844 '#834', -- Win32QueryWindow
3845 atol( hwnd) ||
3846 atol( QW_PARENT), 2)
3847 return hwndFrame
3848
3849defc QueryParent
3850 hWndParent = QueryParent( arg( 1))
3851 dprintf( 'Parent of 'arg( 1)' = 'hwndParent)
3852
3853; ---------------------------------------------------------------------------
3854defproc SetParent
3855 hWnd = arg( 1)
3856 hWndNewParent = arg( 2)
3857 rcx = dynalink32( 'PMWIN', -- dynamic link library name
3858 '#865', -- Win32SetParent
3859 atol( hWnd) ||
3860 atol( hWndNewParent))
3861 return rcx
3862
3863defc SetParent
3864 parse arg hWnd hWndNewParent
3865 rcx = SetParent( hWnd, hWndNewParent)
3866 dprintf( 'rcx = 'rcx) -- 1 = success
3867
3868; ---------------------------------------------------------------------------
3869defproc QueryOwner
3870 hWnd = arg( 1)
3871 hwndOwner = dynalink32( 'PMWIN',
3872 '#834', -- Win32QueryWindow
3873 atol( hwnd) ||
3874 atol( QW_OWNER), 2)
3875 return hwndOwner
3876
3877defc QueryOwner
3878 hWndOwner = QueryOwner( arg( 1))
3879 dprintf( 'Owner of 'arg( 1)' = 'hwndOwner)
3880
3881; ---------------------------------------------------------------------------
3882defproc SetOwner
3883 hWnd = arg( 1)
3884 hWndNewOwner = arg( 2)
3885 rcx = dynalink32( 'PMWIN', -- dynamic link library name
3886 '#864', -- Win32SetOwner
3887 atol( hWnd) ||
3888 atol( hWndNewOwner))
3889 return rcx
3890
3891defc SetOwner
3892 parse arg hWnd hWndNewOwner
3893 rcx = SetOwner( hWnd, hWndNewOwner)
3894 dprintf( 'rcx = 'rcx) -- 1 = success
3895
3896; ---------------------------------------------------------------------------
3897defproc WindowFromId
3898 if arg() = 2 then
3899 hWndParent = arg( 1)
3900 Id = arg( 2)
3901 else
3902 Id = arg( 1)
3903 hWndParent = 1 -- HWND_DESKTOP
3904 endif
3905 hWnd = dynalink32( 'PMWIN', -- dynamic link library name
3906 '#899', -- Win32WindowFromID
3907 atol( hWndParent) ||
3908 atol( Id), 2)
3909 return hWnd
3910
3911; ---------------------------------------------------------------------------
3912defproc QueryCheckValue( hWndParent, Id)
3913 hWnd = WindowFromId( hWndParent, Id)
3914 rcx = windowmessage( 1,
3915 hWnd,
3916 292, -- BM_QUERYCHECK = 0x0124 = 292
3917 0,
3918 0)
3919 return rcx
3920
3921; ---------------------------------------------------------------------------
3922defproc SetCheckValue( hWndParent, Id, fChecked)
3923 hWnd = WindowFromId( hWndParent, Id)
3924 call windowmessage( 1,
3925 hWnd,
3926 293, -- BM_SETCHECK = 0x0125 = 293
3927 fChecked,
3928 0)
3929 return
3930
3931; ---------------------------------------------------------------------------
3932defproc QueryDlgItemText( hWndParent, Id)
3933 Buff = copies( \0, 255)
3934 Len = dynalink32( 'PMWIN', -- dynamic link library name
3935 '#815', -- Win32QueryDlgItemText
3936 atol( hWndParent) ||
3937 atol( Id) ||
3938 atol( length( Buff)) ||
3939 address( Buff))
3940 parse value Buff with Text \0
3941 return Text
3942
3943; ---------------------------------------------------------------------------
3944defproc SetDlgItemText( hWndParent, Id, Text)
3945 TextZ = Text\0
3946 rcx = dynalink32( 'PMWIN', -- dynamic link library name
3947 '#859', -- Win32SetDlgItemText
3948 atol( hWndParent) ||
3949 atol( Id) ||
3950 address( TextZ))
3951 return
3952
3953; ---------------------------------------------------------------------------
3954defproc SetEntryFieldSelect( hWndParent, Id)
3955 pStart = arg( 3)
3956 pEnd = arg( 4)
3957 if pStart = '' then
3958 pStart = 0
3959 endif
3960 if pEnd = '' then
3961 pEnd = 1024
3962 endif
3963 -- If pStart = pEnd, then only the cursor pos. is set.
3964 hWnd = WindowFromId( hWndParent, Id)
3965 call windowmessage( 1,
3966 hWnd,
3967 322, -- EM_SETSEL = 0x0142 = 322
3968 MpFrom2Short( pEnd, pStart),
3969 0)
3970 return
3971
3972; ---------------------------------------------------------------------------
3973defproc EnableWindow( hWndParent, Id, Flag)
3974 hWnd = WindowFromId( hWndParent, Id)
3975 rcx = dynalink32( 'PMWIN', -- dynamic link library name
3976 '#735', -- Win32EnableWindow
3977 atol( hWnd) ||
3978 atol( Flag))
3979 return
3980
3981; ---------------------------------------------------------------------------
3982defproc SetWindowFont( hWndParent, Id, Fontname)
3983 FontnameZ = Fontname\0
3984 Len = length( FontnameZ)
3985 IdPP = 15 -- PP_FONTNAMESIZE = 15L
3986 hWnd = WindowFromId( hWndParent, Id)
3987 rcx = dynalink32( 'PMWIN', -- dynamic link library name
3988 '#938', -- Win32SetPresParam
3989 atol( hWnd) ||
3990 atol( IdPP) ||
3991 atol( Len) ||
3992 address( FontnameZ))
3993 return
3994
3995; ---------------------------------------------------------------------------
3996; Close: Let the app cancel the close before it posts quit.
3997; Quit: Quit the window.
3998defproc CloseWindow
3999 hWnd = arg( 1)
4000 if hWnd = '' then
4001 hWnd = getpminfo( EPMINFO_EDITCLIENT)
4002 endif
4003 call windowmessage( 0, -- 0 = post, 1 = send
4004 hWnd,
4005 41, -- WM_CLOSE = 0x0029 = 41
4006 0, -- mp1
4007 0) -- mp2
4008 return
4009
4010defc CloseWindow
4011 CloseWindow( arg( 1))
4012
4013; ---------------------------------------------------------------------------
4014; Window pos. is saved to EPM -> DEFAULTSWP
4015defproc SaveApp
4016 call windowmessage( 0, -- 0 = post, 1 = send
4017 getpminfo( APP_HANDLE),
4018 62, -- WM_SAVEAPPLICATION = 0x003E = 62
4019 0, -- mp1
4020 0) -- mp2
4021 return
4022
4023defc SaveApp, SaveWindowSize
4024 call SaveApp()
4025
4026; ---------------------------------------------------------------------------
4027defproc MakeWindowTopmost
4028 hWnd = arg( 1)
4029 if hWnd = '' then
4030 hWnd = 1 -- Default is HWND_DESKTOP
4031 endif
4032 Style = dynalink32( 'PMWIN',
4033 '#843', -- Win32QueryWindowULong
4034 atol( hWnd) ||
4035 atol( QWL_STYLE), 2)
4036
4037 if Style bitand WS_MINIMIZED then
4038 opts = SWP_ZORDER bitor SWP_ACTIVATE bitor SWP_RESTORE
4039 else
4040 opts = SWP_ZORDER bitor SWP_ACTIVATE
4041 endif
4042 x = 0
4043 y = 0
4044 cx = 0
4045 cy = 0
4046 rc = 1
4047 rcx = dynalink32( 'PMWIN',
4048 '#875', -- Win32SetWindowPos
4049 atol( hWnd) ||
4050 atol( HWND_TOP) ||
4051 atol( x) ||
4052 atol( y) ||
4053 atol( cx) ||
4054 atol( cy) ||
4055 atol( opts))
4056 if rcx = 1 then
4057 rc = 0
4058 endif
4059 return
4060
4061defc MakeWindowTopmost
4062 call MakeWindowTopmost( arg( 1))
4063
4064; ---------------------------------------------------------------------------
4065; Set window pos and size
4066defc WindowPos
4067 Val = strip( arg( 1))
4068 parse value Val with x y cx cy .
4069 if IsNum( x) & IsNum( y) & IsNum( cx) & IsNum( cy) then
4070 call NepmdSetFrameWindowPos( x, y, cx, cy)
4071 endif
4072
Note: See TracBrowser for help on using the repository browser.