Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29274 Discussions

Graphs in a Fortran Windows application (simple dialog based application)

hpb
Beginner
5,392 Views

Hello,

I posted allready a similar question for a quickwin application.

Now I have Fortran Windows Project, which is configured as a "Simple Dialog Based Application". In this application I also want to show the result of a calculation as a graph.

So my questions are:

Is there a possibility to show the resulting graph in the same dialogwhere the user enters the input data? If yes, which dialog elements do I have to use andwhich functions canI use to show the graph?

If this is not possible, how can I show the graphin adiagram with axes on the screen in a seperate window?Which is the "best" way of working to solve that problem? Are there more than one possibilities? Which one ise the easiest to use?

If I try to use the scigraph utility, no additional window gets opened.Doesthe Scigraph utility work with this kind of application at all or is there a mistake in my program?

I'm using CVF 6.1. Does this revision has restrictions concerning showing graphs?

Any help or example would be great.

Thanks in advance. hpb

0 Kudos
36 Replies
Steven_L_Intel1
Employee
3,370 Views
Scigraph is QuickWin only - it does not work with any other project type. CVF has no specific graphing support at all - you can do most anything you want in a window with Win32 calls.

Do a web search for "pgplot" - it may be of interest. Or there are third party libraries such as Winteracter and GINOMENU that can help.
0 Kudos
anthonyrichards
New Contributor III
3,370 Views

I use CVF 6.6D. Here isa Fortran Windows project developed with itthat displays a dialog box and draws on it by way of a static text control that has been given the Owner-Draw property, after its creation, by editing the resource script. Every time the control needs to be redrawn (because some or all of it has been made visible, or because you want to change the data plotted there), a WM_DRAWITEM Windows message is sent to, or must be sent by you, to the dialog box's window procedure (by default this is called DefDlgProc which you do not need to concern yourself with). Because the control has the Owner-draw property, Windows will not draw it for you. This means that you must intercept the WM_DRAWITEM message and draw the control's background and any other features (such as a graph) you want on it. This is done by what is called sub-classing, where you substitute a new dialog box procedure (called NewDlgProc in the attached code)for the default one. Then you intercept the WM_DRAWITEM message in your new procedure and then pass on all other Windows messages to the original dialog box procedure so that the rest of the dialog box continues to be drawn and function correctly. After you intercept the WM_DRAWITEM message, you do your sums, generate your data and then drawyour graph (or graphs)onto the control's 'device context', which is just a specially-set aside area of memory where a bitmap image of the control is kept, along with details of what background 'brush' and line-drawing 'pen' is to be used. These latter two things can be changed, as the included code shows, so that graphs in various colours can be drawn onto the control.

In order for you to generate a WM_DRAWITEM message to redraw the control and hence replot your new data, you use the InvalidateRect Windows function (giving windows the handle to the Owner-drawn control) to tell Windows to redraw the whole of it. Windows then issues the WM_DRAWITEM command for you.

I have added a couple of buttons to show how you can modify and recompute the graphed data and redisplay it. A screen shot is included in the attached archive. To use the attached code, just unzip it and it should become a useable workspace and project. called OWNERDRAW.If you have any problems with the code, just e-mail me.

0 Kudos
Steven_L_Intel1
Employee
3,370 Views
anthonyrichards:
I use CVF 6.6D.


6.6D???
0 Kudos
anthonyrichards
New Contributor III
3,370 Views
Oops! 6.6C actually!
0 Kudos
hpb
Beginner
3,370 Views

Hello,

my problem still exists. I did meanwhile the following:

I loaded the example project ofanthonyrichards (thank you for your help) and had a look on it. Therein I found a dialog with a rectangular area where the graph(s) should get displaydI think. Seems to be what I need. But unfortunately I cannot built the project, because I get errors while compiling/linking.The error messages are documented in the attached Zip-File in messages.txt.

I also reduced my existing project to a minimumand included it also in the zip-file. In the project there is a dialog with a rectangular area where I want to draw my graphs. Can anybody help me further what kind of object I have to use in the dialog and how I can draw in that area with my existing project. Which functions can I use? Can anyonedraw a sample line in my project?Whatever I try, I'm not successfull. So, is my project anyway applicable to do what I plan? Do I have to configure my project differently?

Thanks in advance hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,370 Views
The problem is that you're using CVF6.1, which is ancient by all reasonable means of measuring. Its DFWIN headers don't contain all the API functions and constants used in Tony's code. I'll give you an overview of necessary changes:

1)
D:src_fortranownerdrawOWNERDRAW.f90(191) : Error: The type of the actual argument differs from the type of the dummy argument. [0]
retint=InvalidateRect(GetDlgItem(dlg%hWnd,IDC_OWNER),0, .true.)

Replace the zero with NULL_RECT

2)
D:src_fortranownerdrawONOWNERDRAW.F90(32) : Error: Not a valid attribute for the DEC$ ATTRIBUTES directive. [DECORATE]
!DEC$ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS: 'SetDCPenColor':: SetDCPenColor

Replace the last line with

!DEC$ATTRIBUTES DEFAULT, STDCALL, ALIAS: '_SetDCPenColor@8':: SetDCPenColor

3) Add
INTEGER, PARAMETER:: DC_PEN = 19

Independently of Tony's code, you might also take a look at the old XFLOGM of mine; apart from other things, it allows for DLG_DRAWITEM callback, for drawing on the owner-drawn static controls. I think it would compile under 6.1 (no guarantees). You may also be interested in XGraph sample; although you could not compile it, you could reuse some tricky code for graph drawing and scaling.

Both XFLOGM and XFTGDI are contained in the XeffortLite sample, which demonstrates drawing in the dialog. Again, I'm not sure if it compiles with 6.1, but you can give it a try.

0 Kudos
hpb
Beginner
3,370 Views

Hello Jugoslavdujic,

thank you for your quick answer. I will try that.

Can you tell me, if my projec I posted is applicable to draw lines in a dialog? Or do I have to reconfigure it with other settings?

Thanks in advance hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,370 Views
Try XFLOGM; first try to build my samples separately, and if they succeed, copy the Xflogm.f90 to your project, and replace all USE DFLOGM with USE XFLOGM. Then, follow the instructions (see DLG_DRAWITEM section, and Remarks therein -- you have to manually edit the .rc file to convert the static control into SS_OWNERDRAW).

For the drawing itself, you have to use DFWIN (Windows API) routines (MSFWIN$Rectangle, SelectObject etc.). Alternatively, you can use the XFTGDI routines, (again, if you manage to compile the XFTGDI.f90 from XeffortLite), as they're simpler to use and offer easier scaling (because they come in _W pairs, similar to QuickWin ones). Good luck, and post here if you have problems.
0 Kudos
anthonyrichards
New Contributor III
3,370 Views

Sorry to hear you have problems with the code. Why not try upgrading? Here's the site:

http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801/?ciid=8008d7c682f02110d7c682f02110275d6e10RCRD

0 Kudos
Steven_L_Intel1
Employee
3,370 Views
CVF 6.1 can't be upgraded for free. You'd have to buy a 6.5 or 6.6 upgrade from soneome who still has an unused copy to sell.
0 Kudos
hpb
Beginner
3,370 Views

Hello JugoslavDujic,

I did as you suggested. I loaded the DialogTest.zip from the page I which I reached with your link (XFlogm). Afterwards I unzipped the file and opened the DialogTest.dsp therein.

But I get the following errors:

--------------------Konfiguration: DialogTest - Win32 Release--------------------
Ressourcen werden kompiliert...
Compiling Fortran...
D:src_fortranDialogTestXFLOGM.F90
D:src_fortranDialogTestDlgTest.f90
D:src_fortranDialogTestDlgTest.f90(61) : Error: The attributes of this name conflict with those made accessible by a USE statement. [IMAGE_BITMAP]
INTEGER,PARAMETER:: IMAGE_BITMAP =0
--------------------^
D:src_fortranDialogTestDlgTest.f90(62) : Error: The attributes of this name conflict with those made accessible by a USE statement. [IMAGE_ICON]
INTEGER,PARAMETER:: IMAGE_ICON =1

and so on until = 8000

What am I doing wrong?

Thanks hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,370 Views
You aren't doing anything wrong -- as noted in the code, these declarations are needed only for CVF (DVF) 5.0. For some reason, your compiler does not recognize the preceding !DEC$IF statement -- just delete the offending lines.

Please bear with us -- the problem is that your compiler, or, precisely, Windows API declarations provided with it, are incomplete (they were upgraded by Compaq/Intel in all subsequent versions, step by step). Since we don't have 6.1 anymore, we're forced to guess what's in there.

The good news is that Xflogm.f90 compiles. The remainder is just the test code.

Please try the same with XeffortLite sample later (it's supposed to have a newer version of Xflogm, as well as Xftgdi.f90); you might encounter similar problems, but I think it's reasonably close to be compilable with 6.1.
0 Kudos
hpb
Beginner
3,370 Views

Hello,

I did as suggested and the errors mentioned disappeared. Now I get the following message:

D:src_fortranDialogTestXFLOGM.F90
D:src_fortranDialogTestDlgTest.f90
Linker-Vorgang luft...
LINK : fatal error LNK1104: Datei "iflogm.lib" kann nicht geoeffnet werden

In a next step I removed the following lines:

!DEC$ IF (.NOT.DEFINED(__INTEL_COMPILER_))
!DEC$ OBJCOMMENT lib: "iflogm.lib"
!DEC$ENDIF

because I think iflogm.lib is for Intel Fortran. The result is:

Compiling Fortran...
D:src_fortranDialogTestXFLOGM.F90
D:src_fortranDialogTestDlgTest.f90
Linker-Vorgang luft...
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGGETRES@12
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGPARSERES@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGID2HWND@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGSENDMESSAGE@16
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGENABLEWINDOW@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGISWINDOWENABLED@4
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGDOCALLBACK@16
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGHWND2ID@4
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGEXECUTEDLGINIT@12
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGDOMODAL@20
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGCREATEFORTDIALOGCLASS@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGDOMODELESS@28
DialogTest.exe : fatal error LNK1120: 12 unaufgeloeste externe Verweise

Then I tried to use dflogm.lib instead of iflogm.lib:

!DEC$ OBJCOMMENT lib: "dflogm.lib"
!DEC$ OBJCOMMENT lib: "user32.lib"
!DEC$ OBJCOMMENT lib: "comctl32.lib"
The result is now:

Compiling Fortran...
D:src_fortranDialogTestXFLOGM.F90
D:src_fortranDialogTestDlgTest.f90
Linker-Vorgang luft...
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGDOMODAL@20
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGCREATEFORTDIALOGCLASS@8
DialogTest.exe : fatal error LNK1120: 2 unaufgeloeste externe Verweise

Any idea what I can do now to get the project running?

Thanks in advance hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,370 Views
hpb:

Compiling Fortran...
D:src_fortranDialogTestXFLOGM.F90
D:src_fortranDialogTestDlgTest.f90
Linker-Vorgang luft...
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGDOMODAL@20
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _DLGCREATEFORTDIALOGCLASS@8
DialogTest.exe : fatal error LNK1120: 2 unaufgeloeste externe Verweise



I think I see what happened: at some point, Compaq changed some prototypes of functions from Dflogm.lib (DlgDoModal received an extra argument, and DlgCreateFortDialogClass was deleted; type DialogExtraBytes was extended). When I was adapting the Xflogm, I didn't know when exactly -- I thought it was in CVF 6.5, but judging on your link errors it was some time between 6.0 and 6.1.

Please open your original Dflogm.f90 (C:Program filesMicrosoft Visual StudioDfInclude) and the Xflogm.f90; compare the lines where the string "650" occurs in the latter -- the test (_DF_VERSION_ < 650 refers to the compiler older than 6.5); change "650" to "610" accordingly (or delete the offending lines).
0 Kudos
hpb
Beginner
3,370 Views

Hello Jugoslav,

I did as you suggested. Now the example program is working smiley [:-)].

In the next step I added the xflogm.f90 to my test project.and I was able to compile it. Unfortunately I have linker errors, where I don't kow how to resolve:

Ressourcen werden kompiliert...
Compiling Fortran...
D:src_fortran est est_dialog_graphXFLOGM.F90
df: info: Some interprocedural optimizations may be disabled when compiling into separate object files
D:src_fortran est est_dialog_graphluk_int_str.for
D:src_fortran est est_dialog_graphekkr.for
D:src_fortran est est_dialog_graphcbfunctions.for
Linker-Vorgang luft...
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlggetres_@12
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgparseres_@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgid2hwnd_@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgsendmessage_@16
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgenablewindow_@8
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgiswindowenabled_@4
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgdocallback_@16
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlghwnd2id_@4
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgexecutedlginit_@12
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _gethwndqq_@4
XFLOGM.OBJ : error LNK2001: Nichtaufgeloestes externes Symbol _dlgdomodal_@24

Do you know a solution?

Thanks in advance hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,370 Views
Boy those are strange -- you seem to have "append underscore to external names" and "external name representation: lowercase" in Project/Settings/Fortran/External procedures. Is there a particular reason for that?

If there is, please switch those off for Xflogm.f90 (in the same Project settings page). Alternatively, !DEC$ATTRIBUTES DEFAULT should be specified for those routines in Xflogm.f90, but (again) I'm not sure in which CVF version !DEC$ATTRIBUTES DEFAULT was introduced.


0 Kudos
hpb
Beginner
3,370 Views

Hello,

yes, you are right. I'm impressed. I changed the settings for the Xflogm.f90 and now I can compile and link my project. When I run it, I get a runtime error if pressing the OK button:

forrtl: severe (157): Program exception - access violation

Image PC Routine Line Source

USER32.dll 7E433513 Unknown Unknown Unknown

.....

When I debug the project I find the routine Dialog2Data where the following function callfailes(xflogm,f90):

!=== end JD's revision =======
case (ctrl_edit)
dummyi = DlgSendMessage( hwndControl, WM_GETTEXT, &
STRSZ, loc(dlg % list(index) % charvalue(1)) )

with

hwndControl = 2557476 and with

dlg % list(index) % charvalue(1) = Undefined adress.

I think "dlg % list(index) % charvalue(1) = Undefined adress" is the problem. But why? Do you know?

Thanks in advance hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,370 Views
I took your code and inserted the Xflogm.f90, but I can't reproduce it.

1) Are you sure you replaced USE XFLOGM everywhere? In your code, you had USE DIALOGM twice and USE DFLOGM once (those are equivalent mutually, but not equivalent with XFLOGM). (I also managed to get a crash if I had USE DFLOGM within ButtonSUB routine).

2) There's an additional catch: XFLOGM will attempt to center the dialog relative to the parent window, not to the screen; since your frame window is at (5000, 5000) you won't see the dialog. Please replace it with (500, 500) for the time being; (there's a better cure, but let's get it to work first).

3) Please take declaration of Dlg out of forms.cmn and move it to the body of PROGRAM; it's not a good idea to have it in a common in general.

4) Minor style note: DlgModal will return IDOK or IDCANCEL, so there's no need for KEY global variable. If you want to manipulate return value, use DlgSetReturn.
0 Kudos
hpb
Beginner
3,370 Views

Hello,

meanwhile my sample project is running with xflogm.

To point 2):My frame window is now in the visible area of the screen, but as you can see in my example code, I always positioned the (new) windows with the upper left corner on the same position as the predecessor. Thats why the users start the application more than one time simultaniously and with the new behaviour all windows are on the same place. Is there a possibility to position the window in the OnDlgInit-Function?

To point 3): I'm forced to remove the declaration of dlg from the common block, otherwise there are compiler errors.

To point 4): The variable key is declared as global, because in the complete project it is used in other routines.

My next questions are now, which controll do I vave to add in the dialog now, and how can I draw lines or write text in it.

Further help would be great.

Thanks in advance hpb

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,282 Views
2) Yes, you can reposition the dialog in OnDlgInit, but remove the "Center" style from the dialog before that.

As for the drawing:
a) add an identifier other than IDC_STATIC to the current frame control, e.g. IDC_DRAWING
b) open the .rc file as text (File->Open->Open as) and replace SS_BLACKFRAME with SS_OWNERDRAW for IDC_DRAWING. Save & close.
c) install the "callback" throug DlgSetSub(Dlg, IDC_DRAWING, OnOwnerDraw)
d) See the OnOwnerDraw routine for how the actual drawing is made (for the start, it is erased by MSFWIN$Rectangle)

Have in mind that:
* OnOwnerDraw is called every time when (a part of) the drawing is physically revealed on the screen
* However, it is not refreshed automatically; when you want to change the drawing, call iSt=InvalidateRect(GetDlgItem(Dlg, IDC_DRAWING), NULL_RECT,.FALSE.)
to "force" OnOwnerDraw to be called (don't CALL it directly!)
* XFTGDI is generally simpler to use than DFWIN drawing routines (which are prone to memory leaks if you're not careful enough to DeleteObject for every thing you create). The XeffortLite sample is more elaborate than DlgTest, and also contains routines for image printing, exporting into WMF and BMP formats (should you ever need it). If you can compile that (replace the Xflogm.f90 with your adapted one), it could be a better place to start.

And, finally, if you don't ever need the QuickWin frame window, it would be better to rebuild your application as "Windows Application" -- just replace PROGRAM with WinMain, as in XeffortLite sample. You will have to re-create the project workspace, though (in order to eliminate "QuickWin application").



0 Kudos
Reply