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

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