lm_lxt 发表于 2014-1-28 17:22:42

Fortran适合科学计算,同时也能编写图形用户界面!

如题。先举几个例子:

1.菜单、工具栏、状态栏:



2.浮动的工具栏和对话框:



3.调用OpenGL绘制贝塞尔曲面:



通过运行发现,程序的执行效率要比Tcl/TK的高!但是在代码编写的劳动量上要远远逊色于Tcl/TK、Purebasic!
贴图片仅仅用来证明Fortran也能干这些工作,当然很多人会认为这些是编译器的扩展,不足为谈。其实,其他语言何尝不是这样!

老房子 发表于 2014-3-1 19:44:25

待续了一个多月还是待续!

aliouying 发表于 2014-3-1 21:15:47

老房子 发表于 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 22:08:26

清风这帖子是来抢第一帖的,第二天他想接着编辑,结果不小心变成发新帖了。

lm_lxt 发表于 2014-3-2 10:57:55

老房子 发表于 2014-3-1 19:44
待续了一个多月还是待续!

最近忙,等有空写详细些。见谅啊。

lm_lxt 发表于 2014-3-2 21:27:48

本帖最后由 lm_lxt 于 2014-3-2 21:30 编辑

Fortran语言编写图形界面有下面两种途径:
1.QuickWin(其实,不建议用它!原因是程序编写没有简化多少,同时失去了灵活性。);
2.Win32 API(建议直接上手学习,楼上的例子采用了这种方法);
   参考书籍:《windows程序设计》,Petzold的大作。
   经过学习发现,Fortran在编写界面方面和C/C++没有任何区别!(除了C++的面向对象。)

楚香饭 发表于 2014-3-2 21:58:40

本帖最后由 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 又何尝不是呢?

lm_lxt 发表于 2014-3-3 03:21:12

楼上对常见的界面库已经总结了,确实,用于fortran的很少,可能winteracter 是最适合的,可惜收费!

lm_lxt 发表于 2014-3-3 11:17:43

fortran编译器对win32 API的接口已经严重老化,比如GDI+都还没有引入,现在的GDI绘制的直线惨不忍睹,除非加入自己的反走样代码。
从intel的编译器看,其发展方向是对fortran最新标准的支持,而相关扩展从CVF继承过来就没有什么变化,最多就是类似在opengl的相关工具库的舍弃上摇摆不定。

lm_lxt 发表于 2014-3-3 11:28:01

这段程序仅仅生成一个空白的窗口,如果你彻底理解了,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

运行结果:

                              
页: [1] 2 3
查看完整版本: Fortran适合科学计算,同时也能编写图形用户界面!