 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Thu Apr 23, 2015 11:35 pm Post subject: |
|
|
John,
You don't get to the line after the last (second) WINIO@ call until you finish interacting with the window. By the time you get to GET_WINDOW_LOCATION the window has ceased to exist, so the call is meaningless. The DESTROY_WINDOW@ is superfluous too.
You need to put GET_WINDOW_LOCATION@ inside a callback function to a %cc closure control format code, thus:
Code: | Test Routine to Get MAX Window size
!
WINAPP
Program MaxWinSize
USE CLRWIN
integer wd, ht
integer ii, X_maxwin, y_maxwin, W_maxwin,h_maxwin, hdl_maxwin
COMMON ii, X_maxwin, y_maxwin, W_maxwin,h_maxwin, hdl_maxwin
integer, external:: closer
x_maxwin=0 ; y_maxmin=0 ; h_maxmin=0 ; w_maxwin=0
!__________________________________________________________________
! Create a window temporarily to get MAX Window SizeGet MAX Window Size
! then Delete It !
ii=winio@("%ww[not_fixed_size,maximise]&")
ii = winio@('%cc&', closer)
ii=winio@("%hw",hdl_maxwin)
print*,'hdl_maxwin = ', hdl_maxwin
print*,'x_maxwin = ', x_maxwin, 'y_maxwin = ', y_maxwin
print*,'h_maxwin = ', h_maxwin, 'w_maxwin = ', w_maxwin
!Call DESTROY_WINDOW@(hdl_maxwin)
!_____________________________________________________
! Create a New window of Same size
wd = w_maxwin; ht = h_maxwin
print*,'h_maxwin = ', h_maxwin, 'w_maxwin = ', w_maxwin
ii=winio@("%sp&",0L,0L)
ii=winio@("%ww[not_fixed_size]&")
ii=winio@("%sz",wd,ht)
!__________________________________________________________________
End Program
INTEGER FUNCTION CLOSER ()
USE CLRWIN
integer wd, ht
integer ii, X_maxwin, y_maxwin, W_maxwin,h_maxwin, hdl_maxwin
COMMON ii, X_maxwin, y_maxwin, W_maxwin,h_maxwin, hdl_maxwin
CALL GET_WINDOW_LOCATION@( hdl_maxwin, X_maxwin, y_maxwin, W_maxwin,h_maxwin)
CLOSER = 0
End |
Apologies it isn't all that neat, and uses COMMON.
Eddie |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Apr 24, 2015 2:20 am Post subject: |
|
|
Eddie,
Thanks for your example; I played around with it, introduced %`cc and learnt a bit more about what is happening. I tried this on my 2-screen setup, where the second screen is on the left. This gives -ve Y and X values. I introduced MODULE and more reporting.
John
(Oh the frustrations of the post size limit ! What about a 10th birthday present? )
Code: | ! Test Routine to Get MAX Window size
!
WINAPP
module my_win_variables
integer ii, X_maxwin, Y_maxwin, W_maxwin, H_maxwin, hdl_maxwin, wd, ht
end module my_win_variables
Program MaxWinSize
USE CLRWIN
use my_win_variables
integer, external :: closer, closed, initial_location
X_maxwin=0 ; Y_maxwin=0 ; H_maxwin=0 ; W_maxwin=0 ; wd=0 ; ht = 0
!__________________________________________________________________
! Create a window temporarily to get MAX Window SizeGet MAX Window Size
! then Delete It !
ii = winio@ ('%ca@&', 'First window - resize, move then close')
ii = winio@ ('%ww[not_fixed_size,maximise]&') ! set window position
ii = winio@ ('%sc&', initial_location) ! call initial_location function to remembre initial location
ii = winio@ ('%cc&', closer) ! control window close : call closer before window is closed
ii = winio@ ('%`cc&', closed) ! control window close : call closed after window is closed
ii = winio@ ('%hw', hdl_maxwin) ! return handle for current window
!
call report_location ( 'Location of first window when completed' )
!Call DESTROY_WINDOW@(hdl_maxwin)
!_____________________________________________________
! Create a New window of Same size
print*, 'Retained window size for next window'
print*, ' H_maxwin = ', wd
print*, ' W_maxwin = ', ht
!
ii = winio@ ('%ca@&', 'Second window - same size? - resize, move then close')
ii = winio@ ('%sp&', 0L,0L) ! set window position
ii = winio@ ('%sz&', wd,ht) ! size window
ii = winio@ ('%ww[not_fixed_size]&') ! set window style
ii = winio@ ('%sc&', initial_location) ! call initial_location function to remembre initial location
ii = winio@ ('%cc&', closer) ! control window close : call closer before window is closed
ii = winio@ ('%`cc&', closed) ! control window close : call closed after window is closed
ii = winio@ ('%hw', hdl_maxwin) ! return handle for current window
!
call report_location ( 'Location of second window when completed')
!__________________________________________________________________
End Program
INTEGER FUNCTION CLOSER ()
USE CLRWIN
use my_win_variables
!
! get location of window as closing
CALL GET_WINDOW_LOCATION@ ( hdl_maxwin, X_maxwin, Y_maxwin, W_maxwin, H_maxwin)
call report_location ( 'Location of window prior to closing' )
wd = W_maxwin; ht = H_maxwin ! retain size
CLOSER = 0
End FUNCTION CLOSER
INTEGER FUNCTION CLOSED ()
USE CLRWIN
use my_win_variables
!
! get location of window after closing
CALL GET_WINDOW_LOCATION@ ( hdl_maxwin, X_maxwin, Y_maxwin, W_maxwin, H_maxwin)
call report_location ( 'Location of window after closing' )
CLOSED = 0
End FUNCTION CLOSED
INTEGER FUNCTION initial_location ()
USE CLRWIN
use my_win_variables
!
! get location of window
CALL GET_WINDOW_LOCATION@ ( hdl_maxwin, X_maxwin, Y_maxwin, W_maxwin, H_maxwin)
call report_location ( 'Location of window when first opened' )
initial_location = 1
End FUNCTION initial_location |
|
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Apr 24, 2015 2:24 am Post subject: |
|
|
Code: | Subroutine report_location (message)
use my_win_variables
character message*(*)
!
print*, ' '
print*, message
print*, 'hdl_maxwin = ', hdl_maxwin
print*, ' X_maxwin = ', X_maxwin
print*, ' Y_maxwin = ', Y_maxwin
print*, ' H_maxwin = ', H_maxwin
print*, ' W_maxwin = ', W_maxwin
print*, ' '
End Subroutine report_location
|
Eddie,
modules even work over multiple posts !!
John |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Fri Apr 24, 2015 9:18 am Post subject: |
|
|
Useful addition. Should help comprehension.
I assume without testing that a window left open with %lw could be examined with GET_WINDOW_LOCATION@ in lines of code executed after the last WINIO@. In such a case, it would perhaps be desirable to first check that the window still exists, although I can't find a Clearwin+ function for that.
Eddie |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Fri Apr 24, 2015 4:59 pm Post subject: |
|
|
L means make the constant a long integer, i.e. INTEGER*4 even if the default is set otherwise. You could set that in the FTN95 cfg config file, or by including OPTIONS(INTL).
With a %ca@ you need to follow it with a string constant (like JC did) or a string variable. If you use a string constant it's the same as %ca[ ] because it is unchangeable. If you use a string variable then at some later point you can change the contents of the string and call WINDOW_UPDATE@ (name_of_variable).
If you want your application to be universal, you may find yourself getting lots of parameters about the screen and other environmental settings:
Code: | CALL GET_OS_VER@ (ID_Platform, Major, Minor)
iHDC = getdc (0)
ixdpi = GetDeviceCaps(iHDC, LOGPIXELSX)
iydpi = GetDeviceCaps(iHDC, LOGPIXELSY)
IX=GetSystemMetrics(SM_CXSCREEN)
IY=GetSystemMetrics(SM_CYSCREEN) |
GetDeviceCaps and GetSystemMetrics are documented online in MSDN.
I don't know about your reported width & height, but heightwise allow for the bar at the bottom of the screen. If you use 'RulerByGeorge' it enables you to measure pixels on the screen (http://www.svet-soft.com/ruler.shtml). It never occurred to me to use GET_WINDOW_LOCATION@ in this context because GetSystemMetrics is better. Maybe there are foibles associated with a maximised window: I noticed in some old code of mine I have:
Code: | IA = WINIO@('%sy[no_border]&') |
so maybe that helps with your missing pixels. I forgot what the difference between the frame and the border is, but there are options in %ww for no_frame and _no_border or naked (which is both). |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Sat Apr 25, 2015 1:22 pm Post subject: |
|
|
John,
It's complicated in more ways than one, because the widths of frames etc are different between different versions of Windows, and the character cell which gives you a lot of the layout in Windows as well as Clearwin+ (but not all, because some is done in pixels) varies with the system font, the version of windows in use, the size of the taskbar and the logical dpi setting - plus, what you want to display in the way of toolbars may depend on the space available.
The trad method is to show the window at a nominal size and let the user maximise it. This doesn't work well in Win8 because that seems to like the newly launched window to be max sized initially.
My applications normally have a master window with the whole client area taken up only by toolbars and a maximum size %gr. I struggle to get the %gr area to fill the remainder of the client area after allowing for the toolbars, and I have experimented with not using Clearwin+ toolbars but running my own, made up from icons, and managing their states myself, but mostly I've used Clearwin's toolbars. Every release of Windows causes my scheme to malfunction, and my study is full of threats of violence to the cannabis-smokers at M$ until I've got it sorted.
The whole logical dpi thing is a nonesensical solution to knowing how many pixels there are, but not knowing the physical size of the screen.
Eddie |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Sun Apr 26, 2015 10:47 am Post subject: |
|
|
Hi John,
Character cell:
Imagine yourself back in the DOS world of 80 characters wide x 25 rows high. If you had a CGA screen of 640x200, the characters would be 8 pixels wide and 8 high, and were all monospaced. If you moved to VGA, which was 640x480, it was possible to have more pixels vertically, or with some graphics cards, to get more rows in. Note that CGA's pixels weren't 'square' - but from VGA onwards they were, and the resolution options blossomed with time.
In Windows, apart from the first few versions maybe, the system font isn't monospaced. Hence, the height of a character cell may be fixed, but its width isn't. So something called the average character cell width is used, which you get by writing out the whole alphabet, and taking the number of pixels divided by the number of letters, then rounding it (up?) you get the average width. The height is simple in comparison: room for ascenders and descenders (up and down bits like bdhl and gjy have etc) and some space top and bottom. Characters always look better with more pixels, and always better with more vertically than horizontally.
Clearwin+ lays out the controls in a window on the basis of a regular grid of these character cells. There's even a format code %gd that draws the grid for you. But, a cell has to be an integer number of pixels wide and high. The upside of this is that it is simple, the downsides are that when things jump to the next cell it is a large jump, exact positioning is difficult (although you do have %ap and %rp) and sometimes text doesn't fit even though the number of characters allowed for is bigger than the number you have (may depend on which characters are involved, where iiiii takes less room than mmmmm). Sometimes you enlarge the font and nothing changes on screen, because original or enlarged, it fits in the same character cell!
The size of an average character cell depends on the font used, which in turn depends on the version of Windows and user selections, so what looks good in 7 may not in 8. It also affects the row spacing, so changes to the number of pixels high of the default font (which is user selectable in Windows) can make things go haywire too. If your user hasn't made any customisation to his Windows, this basically comes down to which version of Windows is he using.
Eddie
Last edited by LitusSaxonicum on Sun Apr 26, 2015 11:48 am; edited 1 time in total |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Sun Apr 26, 2015 11:46 am Post subject: |
|
|
John,
Logical dpi
This is worse. You may remember that a point is 1/72 of an inch. I've had printers with various resolutions in dots per inch (dpi): Epsons at 360, 720 and 1440; loads of others e.g. HP at 300, 600, 1200. Take the Epson at 720 dpi - each point was 10 dots (pixels). If I tell the printer my character size in points, it takes care of the resolution setting and I always get the same output. If I tell it in pixels, then the size print I get depends on the resolution setting. The dpi is a real thing.
There is a problem in doing this with a monitor, because Windows doesn't know how big it is. In the early days, monitors were much the same size, and the same aspect ratio (height to width), plus the dots weren't real, they were driven by frequencies in the firmware of the electron gun. With LCD/LED screens the dots are real, and the range of physical sizes, aspect ratios and resolutions is enormous.
At some stage, it became obvious that with those original monitors, the dot size was such that if Windows assumed that the monitor was 96 dpi and the pixels were square, everything panned out right with the scaling from points to pixels. This may even have come from the Mac (ya! boo! hiss!). And as long as monitors don't vary much in size or resolution (1024x768 anyone?), assuming that is just fine. At least, assuming a standard equivalent dpi lets Windows know if a monitor is widescreen.
But, monitors got higher and higher resolution. I bought a 15" laptop with 1680x1080 resolution. On a 24" monitor, the 96 dpi assumption would look fine, but on the laptop, you'd have difficulty reading anything. This was XP, and Windows was just beginning to address this issue. They had a vested interest in the ways things were done up to then, and hey ho - if you alter the dpi assumption things could scale back into the visibility range. At one stage, you could chose any dpi setting, but they have, in later versions of Windows, settled on 96, 120 and 144 settings, and they call these 'logical dpi' because they don't have any bearing on the 'physical dpi'. Logical means something different this side of the pond, but so what?
Note that 120 is 125% of 96, and 144 is 150%, so you see these percentages bandied about too as well as the terms standard, fine and ultra fine.
As you go through from XP to Vista to 7 to 8, the logical dpi thing gets more and more embedded. What's more, from Vista onwards, Windows will take some of the logical dpi settings and do the scaling for you, whereas in XP you had to cope all by yourself. Windows taking care of it means that your hard work in XP was wasted, and things got bollixed up.
Now, remember those character cells based on the average character size rounded up into n*m pixels? Well, when a non-standard logical dpi setting is in place, they don't scale linearly, because the 'into pixels' roundup is done at the end.
Plus, when there is an ultra-fine logical dpi setting in place, Windows doesn't want you to know what the real pixel resolution is, because if you work to that, and it scales the result you'll get a mess. So when Windows' logical dpi scaling is in effect, it lies about what the physical resolution is. All fine and dandy if you know, but not if you don't. And just when you thought you understood it - it only does it for some logical dpi settings.
You ought to get some help by declaring your application 'logical dpi aware' for which there is a standard function. But, MSDN tells you not to use it, and instead, to put it in your application manifest. If you know what that is, then I salute you.
Fortunately, most devices run in standard mode, and if you don't want to run on a Microsoft Surface or equivalent, or a physically tiny tablet - just ignore it (for now). But beware, if a user installs it on a device that needs a non-standard logical dpi, or the user selects such a setting - your program display windows will go out of alignment at best, or be completely garbled at worst.
Eddie |
|
Back to top |
|
 |
IanLambley
Joined: 17 Dec 2006 Posts: 506 Location: Sunderland
|
Posted: Sun Apr 26, 2015 12:47 pm Post subject: |
|
|
Whilst I'm now totally confused and never bother with dpi as I always initially scale the width of a %gr to be 100.0 units and the height in the ratio of the pixel resolutions.
Here are some useful functions:
Code: |
logical*4 ii
integer*4 rc(4),SPI_GETWORKAREA
SPI_GETWORKAREA = 48
iXsizefull=GetSystemMetrics(SM_CXSCREEN)
iYsizefull=GetSystemMetrics(SM_CYSCREEN)
ii = SystemParametersInfo(SPI_GETWORKAREA, 0, rc, 0)
iXsize=rc(3)
iYsize=rc(4)
INTEGER platformID, major, minor
call get_os_ver@(platformID, major, minor)
IFH = CLEARWIN_INFO@('SYSTEM_FONT_HEIGHT')
|
The work area is the available pixel width and height for the screen, so if your task bar is always visible the height will be smaller than if you have auto-hide set for the task bar. If the task bar is hidden then you may find you have to reduce the pixel height by one or two pixels as using the full value will cover the residual taskbar totally and hovering your cursor at the bottom will not pick up the height. I have menus and icons at the top of the screen and a status text line at the bottom and when choosing the height of the %gr area, I have to reduce the height in accordance with the font height and any borders which may occur. Lots of experimentation but no changes to the code since XP days.
The existence of the task bar and be deduced form the iysize and iysizefull, but I have never catered for the people who like their task bar anywhere else but the bottom.
When a printer is opened, functions already exist to get the pixel resolution and the physical dimensions.
I hope this helps and I'm not being too simplistic.
Ian
PS
SystemParametersInfo description from
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx
SPI_GETWORKAREA 0x0030
Retrieves the size of the work area on the primary display monitor. The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars. The pvParam parameter must point to a RECT structure that receives the coordinates of the work area, expressed in virtual screen coordinates.
To get the work area of a monitor other than the primary display monitor, call the GetMonitorInfo function.
RECT structure definition here
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Sun Apr 26, 2015 4:39 pm Post subject: |
|
|
Ian,
You'll never need to bother with logical dpi as long as your users keep on using the standard setting. When one of them does, you'll know the answer as to why the display is messed up! I've only really come across it once, and that was with an XP laptop of my own.
There are some useful additional functions here, and now I'll look up SystemParametersInfo.
I've found oddities with %gr and an initially maximised window where the %gr doesn't fill the remaining client rectangle after the toolbars are taken into consideration. My workaround has been to get the available screen width and height then take off the frames etc, but not knowing your function I've taken off the system taskbar.
Eddie |
|
Back to top |
|
 |
IanLambley
Joined: 17 Dec 2006 Posts: 506 Location: Sunderland
|
Posted: Mon Apr 27, 2015 7:01 am Post subject: |
|
|
John,
I am glad that I am not alone in hating C, C+ C++, or any other snobby language that generally looks down of the excellence that is Fortran.
These structures are just like the Fortran user type definitions (or "record" statement from VAX Fortran77), which I always seem to forget to use until I am a long way into a program. Just remember:
Code: |
byte = Integer*1
int = Integer*2
long = Integer*4
float = Real*4
double = Real*8
bool = logical*?
|
As I say, just the same but without the consistency, logic and simplicity.
I was programming something in C++ for the Arduino microprocessor thing which uses a subset of C++ (C-- i think!). Painful! Especially formatted i/o. Fortunately I was just doing it for the "learning" and not to support my family.
They seem to have needed to change the names of everything we once held dear and understood.
I feel sorry for the younger generation at college who have to specialise in the semantics of the modern languages before using them as a tool to solve the problem that they are really there to learn.
Ian
PS
Did I go too far? |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Mon Apr 27, 2015 11:58 pm Post subject: |
|
|
Ian,
I don't think you went too far and I also agree with you. The problem we have is that those who are controlling the direction of Fortran do not appear to agree with us.
I have done courses in Fortran and C and much prefer the approach that Fortran offers. Complex coding structures are a recipe for lots of bugs and that is the direction that Fortran is heading. Holding up a sign saying go back is mostly ridiculed and not fully appreciated.
John |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Mon May 04, 2015 6:57 am Post subject: |
|
|
I have not followed the detail in this thread and I may be missing the point but the following works fine for me...
Code: | winapp
program main
integer i,winio@
character(len=1024) buff
character(len=80) status
buff = " "
status = "OK"
i = winio@("%ww[maximise]&")
i = winio@("%ca[My Caption]&")
i = winio@("%30.20re&",buff)
i = winio@("%ob[status]%80st%cb",status)
end |
|
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Wed May 06, 2015 10:44 am Post subject: |
|
|
The result is a call to ShowWindow(hwnd, SW_SHOWMAXIMIZED) where hwnd is the Windows handle for the main window.
Maybe you need a similar call for the child window that contains the controls and scroll bars. |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Thu May 07, 2015 9:48 am Post subject: |
|
|
John,
Put it in the callback to %sc. This is where everything you want done after the window is created should go. You can't put it inline with the WINIO@s because it has to be called after the window is created.
You have to pass the window handle to the callback, which I do via COMMON, and you might do by making the callback function CONTAINSed somewhere or other.
The callback to %sc is where you might also do the initial graphics (we discussed that) and handle the command line to see if the program was invoked by clicking on an associated file - if you do that before you open the main window then your startup may be slowed, plus, if you have to handle any errors, they look odd before your program main window has opened.
Eddie |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|