QuickWin and Windows API

QuickWin and Windows API

Bild des Benutzers NotThatItMatters

I have created a Fortran app with QuickWin which makes use of a few user32 Windows API calls.  Why?  The app needs to build a dynamic menu structure where menu items come and go according to the whims of a governing input file.  The app also needs to properly post-process in case the user pushes the red X in the upper right-hand corner of the window.  Anyway, I had thought I would be able to handle these things strictly with QuickWin but have not been able.

The problem I am having with the app is that if any of the menus are active upon program termination, the application hangs as if in an infinite loop.  I am using a few calls to user32.  The final call is to the following skeletal routine which evidently does not work.

SUBROUTINE DESTROY_WINDOW()
INTEGER (KIND = 4) ITEMID
INTEGER (KIND = LRESULT) RESULT
ITEMID = SETACTIVEQQ(0_4)
WIN_HANDLE = GETHWNDQQ(QWIN$FRAMEWINDOW)
IF (WIN_HANDLE /= -1_HANDLE) THEN
IF (GETEXITQQ() == QWIN$EXITNOPERSIST) THEN
RESULT = SendMessage(WIN_HANDLE, WM_DESTROY, 0_fWPARAM, 0_fLPARAM)
END IF
END IF
END SUBROUTINE DESTROY_WINDOW

34 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Bild des Benutzers Steve Lionel (Intel)

I believe the problem here is that QuickWin has its own message processing loop and it doesn't know how to deal with the messages you are sending. I know there are some forum users more experienced with this sort of thing than I and they may comment, but what you want may not be possible with QuickWin. Perhaps you can use "subclassing", which lets you add on to QuickWin's message processing.  The Poker sample demonstrates this.

Steve
Bild des Benutzers NotThatItMatters

The main difference between the Poker sample and the app I run is that Poker is purely interactive whereas my app is a glorified status bar. All underlying display is based on the running of a simulation.  I am providing a few pieces of user interaction to allow the user to modify the data display.  The underltying start/stop of the application is usually governed by the simulation, but at times the user may want to terminate the simulation early or to modify what is being illustrated.  This is the need for user interaction.  I have done most coding based on a menu-driven QuickWin app, but the need to have a dynamic menu for data display and the ability to gracefully terminate with the user hitting the red X, have both caused the trouble with inclusion of Win32 API calls. If there is some other method to handle what I am trying to handle, I am all ears.

Bild des Benutzers Steve Lionel (Intel)

You may be able to accomplish what you want with a modeless dialog box.

Steve
Bild des Benutzers NotThatItMatters

Is there a sample of modeless dialogs within the samples?  Or elsewhere?

Bild des Benutzers Sergey Kostrov

>>...Is there a sample of modeless dialogs within the samples? Or elsewhere?

Are you looking for C/C++ or Fortran samples with modeless dialogs?

Bild des Benutzers Steve Lionel (Intel)

The Whizzy sample shows dialogs. The only difference between modal and modeless is that a modal waits for the user to dismiss it before the program continues, and a modeless effectively runs in parallel with callbacks when the user clicks on a control. These can be used from any kind of application. So you could float a dialog with a cancel button, keep updated status in a text control, etc.

Steve
Bild des Benutzers Paul Curtis

You create modeless dialogs by first calling CreateDialogParam(), which returns a handle to the newly created modeless dialog but does not display it, and then calling ShowWindow() to start the display.  CreateDialogParam() requires as an argument the LOC() of the dialog's proc function (which you have written and thus readily know the LOC of), and the proc needs, among its other tasks, to process the standard IDOK and IDCANCEL exit operations.  This is all standard WinAPI programming, easily realized in IVF, but programming at this level of detail may be more difficult in Quickwin.

Bild des Benutzers Steve Lionel (Intel)

You can use the Fortran dialog support in module IFLOGM rather than calling the Windows API - it may meet your needs and is pretty easy to use. You don't need to do anything special to use dialogs in QuickWin. See Creating Fortran Applications that use Windows API, QuickWin or dialog features for the documentation.

Steve
Bild des Benutzers NotThatItMatters

I have a somewhat fully featured Fortran QuickWin Graphics application that requires a bit more, but as I have noted the results have been unacceptable.  Attached is a screen shot of a running application showing a dynamic menu with multiple items.  I need to be able to do a few things with this application: (1) be able to use a call back for the menu shown which gives me access to which item is picked and a way to change the display based on the item picked; (2) a means for gracefully closing the program when the user chooses the close button.  I already have a "graceful" exit under the Operation menu which will stop the program running and tidy up the output files generated.

Anlagen: 

AnhangGröße
Herunterladen appdemo.png33.29 KB
Bild des Benutzers Steve Lionel (Intel)

I will admit that I am not an expert in QuickWin, but I'd have thought you could do item 1 through the supported API. For any of the menu items you can designate a routine to be called when that item is selected, and that can do pretty much anything. You will need separate routines for each item, though, since the callback doesn't pass anything more than a checked/unchecked flag. But there's MODIFYMENUFLAGSQQ and MODIFYMENUROUTINEQQ that may be of use.

Item 2 should be able to be done by establishing a routine that gets called when a "Window Close" message is sent. You may need to use "subclassing" to get this to work in a QuickWin app - I'm sure some of the users here will know more than I about this.

P.S. I suggest modifying your forum "display name" to not be your email address.Click on the yellow triangle next to your name near the top of the page, select Dashboard, and you can edit your profile.

Steve
Bild des Benutzers NotThatItMatters

Perhaps it was not obvious from the screen shot, but the display menu has the default "Field" item, but the other items get appended as the simulation proceeds.  The choice of an item on the menu changes the display to mirror the item.  So, if I pick A5 then item A5 gets displayed both graphically and in the text box ticker at the bottom.  With the simulation shown there are 15 possible items.  With some simulations there may be only one, or 250 or more.  It would be somewhat ridiculous to write 250 callback functions on the off chance that 250 items show up in this dynamic menu.

Bild des Benutzers app4619

In QuickWin You don't get any option for the menu selection other than what Steve stated (the checked flag).  It might be better haveing a floating modeless dialog  with a drop down combo box to select these items which you could then handle via a single call back. Either that or you are left with making 250 callbacks for the menu that could be one line routines that call a single routine with the approapriate parameter... not elegant but not that much work either, you could write a 10 line programs that writes the source for the calbacks!

Bild des Benutzers Steve Lionel (Intel)

Yes, app4619's suggestion of a modeless dialog is what I was thinking of earlier. It gives you a lot more flexibility.

Steve
Bild des Benutzers NotThatItMatters

So, if I am understanding the suggestion, the idea would be to omit the "Display" menu in the QuickWin app and replace it with a second modeless floating dialog which holds the same data as the fixed menu.  How does one manage (marshall?) the two pieces, as in the QuickWin piece for the graphics and display and the "separate" modeless dialog box?

Bild des Benutzers app4619

The modeless dialog runs as a separate thread. You can minimise it, if it is in the way or close it and reopen via the menu or indeed you could register a mouse event for clicks on your graphics area to re-pop the dialog when it is closed. Just some ideas. You can still have your other menus or dispense with then and have all the menu interaction via items on the dialog.

Bild des Benutzers dboggs

Unless I'm mistaken, the documentation for Quickwin as well as the classic text "Compaq Visual Fortran" by Lawrence, state (emphatically in fact) that modeless dialog boxes are not possible in Quickwin--it's just an inherent limitation of the way Quickwin works. Maybe I misunderstood. But--do you guys know that your suggested solution will actually work, or is it just wishful thinking? If modeless dialog boxes are indeed possible then I need to learn a lot more about Quickwin.

Bild des Benutzers Steve Lionel (Intel)

Hmm - perhaps I was hasty in suggesting a modeless dialog. Upon review, you do need to be able to process messages in a message loop. This may still be possible - I'll see if I can work it out but ity may be a while.

Steve
Bild des Benutzers app4619

I use modeless dialogs all the time in quickwin... use DlgModeless call rather than dlgmodal !??!?

Bild des Benutzers app4619

I use modeless dialogs in quickwin all the time, that is what the call dlgmodeless does....

Bild des Benutzers Steve Lionel (Intel)

Something has to handle the messages for the modeless window - perhaps QuickWin does that automatically.

Steve
Bild des Benutzers jimdempseyatthecove

FWIW I use the following:

! some place in main thread, may occur periodically (as user has option to kill dialog without killing app)
if(.not. ControlPannelRunning) then
  ! before  creating the dialog box insert values that may be examined/modified
  ! by the dialog box
  vIntegrationStepsize = DLHOST
  IntegrationStepsize = DLHOST
  ! Create seperate thread to run the Modal Dialog control pannel
  ControlPanelHandle = CreateThread(&
   & NULL, &
    & ControlPanelStack, &
    & loc(ControlPanel), &
    & loc(ControlPanelArg), &
    & ControlPanelFlags, &
    & loc(ControlPanelThread_ID))
  ! Check for CreateThread error here (if so inclined)
  !...
  ! Wait until flag set by control pannel thread
  ! indicates initialization complete
  do while(.not. ControlPannelRunning)
    milliseconds = 500
    call sleepqq(milliseconds)
  end do
  ! indicate for my thread that additional work needs to be done
  INIT_AVFRT_AllocateMemory = .false.
  AVFRT_Running = .true.
  ! My code has a Pause/Continue button, as well as [X]
  ! if Pause was set as default startup, then wait for Continue or [X]
  do while ((ControlPanelPause .eq. .true.) .and. (ControlPanelExit .eq. .false.))
    milliseconds = 500
    call sleepqq(milliseconds)
    call    Update_AVFRT('INIT_AVFRT') ! while in Pause allow for manipulation of 3D graphics
  end do
endif
! end of code in main thread (or subroutine periodically called from main)
{seperate source}
integer(4) FUNCTION ControlPanel(arg)
!DEC$ ATTRIBUTES STDCALL, ALIAS:"_controlpanel" :: ControlPanel
    USE IFLOGM
    use   GlobalData
    implicit none
    INCLUDE 'RESOURCE.FD'
    integer(4),POINTER :: arg
    integer(4) returnVal, ns
    CHARACTER(256) text
    LOGICAL retlog
    external ControlPanelCallBack
    retlog = DLGINIT( IDD_DIALOG1, ControlPanelDlg )
    if(.not. retlog) write(*,*) "Dialog error for IDD_DIALOG1"
    call DlgSetTitle( ControlPanelDlg, ControlPanelTitle )
...
    ControlPannelRunning = .true.
    returnVal = DlgModal( ControlPanelDlg ) ! Doesn't return unless cancled (or IDC_event not specified)
    ControlPanelExit = .TRUE.
    ControlPanelPause = .FALSE.
    ControlPanel = returnVal
end FUNCTION ControlPanel
SUBROUTINE ControlPanelCallBack( dlg, id, callbacktype )
!DEC$ ATTRIBUTES DEFAULT :: ControlPanelCallBack
  USE IFLOGM
    use GlobalData
    implicit none
    INCLUDE 'RESOURCE.FD'
  TYPE (dialog) dlg
  INTEGER id, callbacktype, iStat
  CHARACTER(256), automatic :: text
  LOGICAL retlog
  INTEGER cel, far, retint
  real(8), automatic :: xyz(3)
  text = 'undefined'
  ControlPanelPauseRefresh = .true.
  NextDisplayTime = 0 ! update now
  SELECT CASE (id)
    CASE (IDC_RADIO1)
    ! Radio button 1 selected by user so
    ! change display accordingly
      vIavDisplayFrame = 0   ! vIavDisplayFrame = 0 Inertial Frame
      ! vIavDisplayFrame = 1 Orbital Frame
    CASE (IDC_RADIO2)
...
  END SELECT
END SUBROUTINE ControlPanelCallBack

This uses a seperate thread running a Modal Dialog (not modeless).

Jim Dempseyt

www.quickthreadprogramming.com
Bild des Benutzers jimdempseyatthecove

I should add. The main app is a console application (compute intensive parallel OpenMP), using a seperate thread to run a Modal Dialog Box. The application also uses "CALL avNewViewer(viewerID)" zero, one, or multiple times to create zero, one or more Intel Array Visualizer processes connected to the applicaiton. IOW I can have multiple display processes running concurrently with the computation process showing different aspects of the simulation. e.g. multiple 3D views from different perspectives, and/or 2D charts.

Jim Dempsey

www.quickthreadprogramming.com
Bild des Benutzers app4619

Zitat:

Steve Lionel (Intel) schrieb:

Something has to handle the messages for the modeless window - perhaps QuickWin does that automatically.

Yes is must do that or more specifically windows will, the quickwin routines are afterall just a wrapper for standard windows api functionality.  You can capture the [x] for the modeless dialog by having a callback subroutine to to dialog name itself which will be called with the callback type set to DLG_DESTROY when the x is hit or DLG_INIT when the doalog it is first displayed after dlgmodeless is called.

I normal check something like:

if(mydlg%DLGID.ne.0 .and. mydlg%HWND.ne.0 ) return ! dlg is already initialised AND active

before calling dlgmodeless so I don't end up with 2 instances on the screen

Bild des Benutzers app4619

why do my posts disappear and then appear an hour or three later? No message about being 'moderated' was given?

Bild des Benutzers dboggs

Well I stand corrected--I guess. I'm sure the older documentation I was familiar with stated that modeless dialog boxes could not be used with Quickwin, but the current documentation only IMPLIES that it cannot. Or at least that is what I infer. It says that modeless boxes are "typically used in a Windows application" while "modal boxes can be used in any application," and when you look up DLGMODELESS in the A-Z reference, under Compatibility, it lists "Windows Console DLL Lib" but Quickwin is conspiculously absent.

But if it works, it works.

Bild des Benutzers NotThatItMatters

This is a little something along the lines of "and now, for something completely different..."  I have been reading Using Intel Visual Fortran to Create and Build Windows-Based Applications and have noted most dialog-based code has the following stuff at the top of the code:

USE IFLOGM
IMPLICIT NONE
INCLUDE 'RESOURCE.FD'

My project for not quite obvious reasons has a "resource.h" file which looks like a C include file.  It also includes a version.h file for executable versioning.  I am noting the symbols I need are within this file but apparently not readily available to the Fortran code.  Any hints as to how I might get these symbols or perhaps reconfigure the code?

Bild des Benutzers app4619

There is a tool deftofd to convert, it can be run from in VS but I use from a script..

"C:\Program Files (x86)\Intel\Composer XE 2011 SP1\bin\ia32\deftofd.exe" resource.h >resource.fd

Bild des Benutzers Steve Lionel (Intel)

There's instructions for setting up deftofd in Using Intel®Visual Fortran to Create andBuild Windows*-Based Applications - search for deftofd.

Steve
Bild des Benutzers NotThatItMatters

Now that this small problem is settled, I am having another small problem that I cannot resolve.  The compiler is complaining:

error #6423: This name has already been used as an external function name.

Most compiler errors are self-explanatory.  This one has me stumped.  Any ideas?

Bild des Benutzers app4619

what is the name it objects to? The is something that is  declared twice.

Bild des Benutzers NotThatItMatters

Actually, removing the error was simple.  Let me show how it arose:

CHARACTER (LEN = 8) FUNCTION WHATEVER(IW)
...
! Reference to function was as follows:
A = WHATEVER(I)(1:5)
! The substring yielded the error.  Without it, it compiles fine.

Bild des Benutzers Steve Lionel (Intel)

You can't substring a function call. But in this context WHATEVER is the result value, which is a scalar, so the (I) is incorrect and made it look like a functiion call.

If you want it to be a function call, you have to declare the function RECURSIVE and use the RESULT clause to give the result a different name. But you still can't substring a function result.

Steve
Bild des Benutzers NotThatItMatters

Getting back to the problem at hand, I would like to launch a QuickWin SDI which has at its core a few menus and a client area which, if right-clicked, will launch a modeless dialog box.  The dialog box will have a drop-down list of choices and the customary OK and Cancel buttons.  I would like the dialog to disappear if (1) the user presses cancel, (2) the user presses the closing X (just like cancel), (3) the user presses OK which then grabs the user's choice from the drop-down list, and (4) the original QuickWin app quits.  Most of the first three would seem to follow with an appropriately formed

IRESULT = REGISTERMOUSEEVENT(IUNIT, MOUSE$RBUTTONDOWN, MouseLaunch)
.  The MouseLaunch routine would initialize the dialog and its contents.  The question then is where the message pump goes.  Is it part of MouseLaunch?  Should I be worried about the underlying QuickWin app quitting with the modeless dialog active?

Melden Sie sich an, um einen Kommentar zu hinterlassen.