Fortran适合科学计算,同时也能编写图形用户界面!
如题。先举几个例子:1.菜单、工具栏、状态栏:
2.浮动的工具栏和对话框:
3.调用OpenGL绘制贝塞尔曲面:
通过运行发现,程序的执行效率要比Tcl/TK的高!但是在代码编写的劳动量上要远远逊色于Tcl/TK、Purebasic!
贴图片仅仅用来证明Fortran也能干这些工作,当然很多人会认为这些是编译器的扩展,不足为谈。其实,其他语言何尝不是这样!
待续了一个多月还是待续! 老房子 发表于 2014-3-1 19:44
待续了一个多月还是待续!
请看帖:[讨论]Fortran适合科学计算,界面交给Tcl/TK、PureBasic!
http://www.fcode.cn/bbs/forum.php?mod=viewthread&tid=15&fromuid=37
(出处: Fortran Coder)
清风这帖子是来抢第一帖的,第二天他想接着编辑,结果不小心变成发新帖了。 老房子 发表于 2014-3-1 19:44
待续了一个多月还是待续!
最近忙,等有空写详细些。见谅啊。 本帖最后由 lm_lxt 于 2014-3-2 21:30 编辑
Fortran语言编写图形界面有下面两种途径:
1.QuickWin(其实,不建议用它!原因是程序编写没有简化多少,同时失去了灵活性。);
2.Win32 API(建议直接上手学习,楼上的例子采用了这种方法);
参考书籍:《windows程序设计》,Petzold的大作。
经过学习发现,Fortran在编写界面方面和C/C++没有任何区别!(除了C++的面向对象。)
本帖最后由 chuxf 于 2014-3-2 22:00 编辑
lm_lxt 发表于 2014-3-2 21:27
Fortran语言编写图形界面有下面两种途径:
1.QuickWin(其实,不建议用它!原因是程序编写没有简化多少,同 ...
归根结底,都是对操作系统功能的封装。
Win32 API 算是比较底层的。在这方面,几乎所有语言都是类似的。不过,因为 windows应用层大多数是C开发的,所以很多接口更容易,比如 \0 结尾的字符串,一些64位整数的合成宏,一些特殊类型的指针。使用 Fortran 就比较麻烦一些。
QuickWin 其实是 Visual Fortran 开发商对API的封装,但是效果不好而已。至少我是不怎么喜欢。
除此之外,winteracter 是一个比较不错的封装(http://www.winteracter.com),考虑了很多科学计算的约束,但是功能还不够多,而且封装得太深,以致于获得一个对话框的句柄都很困难。使用了 winteracter 的应用,如果想调用底层 Win32 API,问题会比较多。Lahey 与 winteracter 合作,搞了个 WisK,我感觉是一回事。(http://www.lahey.com/wisk.htm)
Silverfrost Ftn95 也有自己的封装,叫 ClearWin+ 和 Simdem(http://www.simfit.org.uk/simdem.html)
只是听说,没有实际用过。
另有一个Xeffort的界面库,没用过。这些都是对WinAPI的封装。
实际上,MFC 又何尝不是呢? 楼上对常见的界面库已经总结了,确实,用于fortran的很少,可能winteracter 是最适合的,可惜收费!
fortran编译器对win32 API的接口已经严重老化,比如GDI+都还没有引入,现在的GDI绘制的直线惨不忍睹,除非加入自己的反走样代码。
从intel的编译器看,其发展方向是对fortran最新标准的支持,而相关扩展从CVF继承过来就没有什么变化,最多就是类似在opengl的相关工具库的舍弃上摇摆不定。 这段程序仅仅生成一个空白的窗口,如果你彻底理解了,win32编程或许没有想象的那么复杂!
Module VarGlob
integer( kind = 4 ) ::results! 存储函数的返回值
logical( kind = 4 ) ::logicalt! 存储函数的返回值
End Module VarGlob
! windowing程序开始执行的地方(操作系统自动识别)
integer function WinMain( hInstance, hPrevInstance, lpszCmdLine, nCmdShow )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
!DEC$ ENDIF
USE IFWIN!包含有用的模块
USE VarGlob!有用的数据模块
Implicit None
integer( kind = 4 ) ::hInstance!定义窗口的实例
integer( kind = 4 ) ::hPrevInstance!定义句柄
integer( kind = 4 ) ::nCmdShow!窗口的显示方式
integer( kind = 4 ) ::lpszCmdLine!指向字符串的指针
!定义函数接口,注意这一段是必须的
interface
integer*4 function MainWndProc ( hwnd, message, wParam, lParam )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_MainWndProc@16' :: MainWndProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'MainWndProc' :: MainWndProc
!DEC$ ENDIF
integer( kind = 4 ) :: hwnd
integer( kind = 4 ) ::message
integer( kind = 4 ) ::wParam
integer( kind = 4 ) :: lParam
end functionMainWndProc
end interface
type (T_WNDCLASS) :: wc!窗口类结构体
type (T_MSG) :: msg !消息结构体
integer( kind = 4 ) :: hWnd
character*100 lpszClassName,lpszAppName
lpszClassName = "Generic"C !窗口类名
lpszAppName = "windowing程序框架"C!窗口标题
if(hPrevInstance .eq. 0) then
wc%lpszClassName = LOC(lpszClassName)!窗口类名
wc%lpfnWndProc = LOC(MainWndProc)!窗口回调函数
wc%style = IOR(CS_VREDRAW , CS_HREDRAW) !窗口风格
wc%hInstance = hInstance!窗口实例
wc%hIcon = LoadIcon( NULL, IDI_WINLOGO)!程序图标
wc%hCursor = LoadCursor( NULL, IDC_CROSS )!程序光标
wc%hbrBackground = GetStockObject(BLACK_BRUSH)!窗口背景颜色
wc%lpszMenuName = 0!菜单名
wc%cbClsExtra = 0!无附加消息
wc%cbWndExtra = 0
results = RegisterClass(wc)!注册窗口类
end if
!创建窗口
hWnd = CreateWindowEx(0, &!窗口扩展样式
lpszClassName, &!窗口类名
lpszAppName, &!窗口标题
INT(WS_OVERLAPPEDWINDOW), &!窗口的风格
CW_USEDEFAULT, &!左上角坐标X
0, &!左上角坐标Y
CW_USEDEFAULT, &!窗口宽度尺寸
0, &!窗口高度尺寸
NULL, &!父窗口句柄
NULL, &!主菜单句柄
hInstance, &!窗口实例句柄
NULL &!附加信息的指针
)
!显示窗口
results = ShowWindow( hWnd, SW_SHOWNORMAL)
!进入消息循环
do while( GetMessage (msg, NULL, 0, 0) .NEQV. .FALSE.)
results = TranslateMessage( msg ) !翻译消息
results = DispatchMessage( msg ) !将消息传给windows,然后由windows传给回调函数
end do
WinMain = msg%wParam
End function WinMain
integer function MainWndProc ( hWnd, message, wParam, lParam )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_MainWndProc@16' :: MainWndProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'MainWndProc' :: MainWndProc
!DEC$ ENDIF
USE IFWIN!包含有用的模块
USE VarGlob!有用的数据模块
Implicit None
integer( kind = 4 ) :: hwnd
integer( kind = 4 ) ::message
integer( kind = 4 ) ::wParam
integer( kind = 4 ) :: lParam
select case ( message )
case (WM_DESTROY)
call PostQuitMessage( 0 )
case default
MainWndProc = DefWindowProc( hWnd, message, wParam, lParam )
end select
end function MainWndProc
运行结果: