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

Using DwmEnableComposition

Simon_Geard
New Contributor I
2,854 Views

I have a Fortran application with an embedded OpenGL window. I need to call DwmEnableComposition to turn off Aero so that the buttons refresh correctly but I can't work out how to do it. I've added Dwmapi.lib to the linker line but still get

unresolved external symbol dwmiscompositionenabled referenced in function WinMain

My interface is

        integer(LRESULT) function DwmEnableComposition(c) bind(c)
            import
            integer(UINT), value :: c
        end function DwmEnableComposition

and my calling sequence is

         lret = DwmIsCompositionEnabled(compositionEnabled)
         if (compositionEnabled) then
             DWM_EC_DISABLECOMPOSITION = 0
             lret = DwmEnableComposition(DWM_EC_DISABLECOMPOSITION)
         else
             compositionEnabled = .false.
         end if

Any ideas greatly appreciated.

 

0 Kudos
14 Replies
andrew_4619
Honored Contributor III
2,854 Views

You need to add the STDCALL directive and probably also need the name alias like the example below, to get the correct call name case and decoration.

        subroutine AVIFileInit() bind(C,NAME="AVIFileInit")
            !DEC$ ATTRIBUTES STDCALL  :: AVIFileInit
        end subroutine AVIFileInit

.

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

As a OpenGL user I am intrigued by "so that the buttons refresh correctly" Is this in the opengl window or in the other windows? Or do you have dialogs that are the children of the OGL window?

 

0 Kudos
Simon_Geard
New Contributor I
2,854 Views

Thanks for that - the name aliasing worked.

Unfortunately this has not solved the problem. I'll try to explain. The application main window contains an embedded OpenGL window and two buttons. These buttons are created with the following code

[fortran]
    ! Create the dialog box
    lret = DlgInit(IDD_EXITBUTTONS, exit_buttons_dlg)

    ! Set up callbacks for the buttons
    lret = DlgSetSub(exit_buttons_dlg, IDC_SAVE, exit_button_save)
    lret = DlgSetSub(exit_buttons_dlg, IDC_FINISH, exit_button_finish)
    
    ! Child dialog boxes are displayed using DlgModeless
    lret = DlgModeless(exit_buttons_dlg, SW_SHOWNA, hwndParent)

[/fortran]

The main window is created with

[fortran]

    ghMenu = LoadMenu(hInstance, LOC(lpszMenuName))
    if (ghMenu == 0) goto 99999
    haccel = LoadAccelerators(hInstance, LOC(lpszAccelName))
    if (haccel == 0) goto 99999
    gr_width = 1000
    gr_depth = 800

    ! Create the window so that it cannot be resized
    ghwndMain = CreateWindowEx(  0, lpszClassName,                 &
                                 lpszAppName,                      &
                                 INT(WS_OVERLAPPED .or. WS_CAPTION .or. WS_SYSMENU .or. WS_MINIMIZEBOX  .or. WS_CLIPCHILDREN),         &
                                 CW_USEDEFAULT,                    &
                                 0,                                &
                                 gr_width,                         &
                                 gr_depth,                         &
                                 NULL,                             &
                                 ghMenu,                           &
                                 hInstance,                        &
                                 NULL                              &
                              )
    if (ghwndMain == 0) goto 99999
    lret = GetClientRect( ghwndMain, wrect)
    lret = ShowWindow( ghwndMain, nCmdShow )


[/fortran]

The problem is that when the application starts up the buttons aren't visible (although they can be pressed). If I iconify/deiconify the buttons are still not visible. If I drag the main window they immediately become visible. The application also has menus and if any of them are posted the buttons become visible.

 

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

In the dlgmodeless call what id hwndparent is it ghwndMain and why SW_SHOWNA and not SW_SHOW? 

I suspect you could also bodge it by getting the handle of the button and using the SDK to send a paint message to that handle.

..and another thought do you have WS_DISABLED in the resource attributes  for the buttons or dialog? 

0 Kudos
Simon_Geard
New Contributor I
2,854 Views

Neither the buttons nor the dialog are disabled in the resources file. Using SW_SHOW makes no difference (although it does look like a better choice). When the dialog is created ghwnMain is still 0.  I'll look again on Monday and see what enquiring the button info returns.

Thanks.

 

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

So do you create the dialog before you create the main Window and that is why ghwndMain=0?  I would suggest creating the dialog after lret = ShowWindow( ghwndMain, nCmdShow )

and passing ghwndMain as the parent in the DlgModeless call. The paint suggestion would look something like below though I am not saying this will work but might be worth a try. 

 

                    ret  = SendMessage(GetDlgItem(exit_buttons_dlh%hwnd, IDC_SAVE), WM_PAINT, 0_fwparam, 0_flparam) ! to send Wm_paint to the button

                    ret  = SendMessage(exit_buttons_dlh%hwnd, WM_PAINT, 0_fwparam, 0_flparam) ! to send Wm_paint to the dialog



 

0 Kudos
IanH
Honored Contributor III
2,854 Views

WM_PAINT has magic powers so I'd advise against sending it "manually" - try an InvalidateRect and UpdateWindow pair instead.

Consider using the Visual Studio utility Spy++ to investigate the window hierarchy and relevant window properties when you have these bizarre buttons - oddities there (position, z-order, clipping related window styles) might give you a hint as to what is going wrong.

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

IanH wrote:

WM_PAINT has magic powers so I'd advise against sending it "manually" - try an InvalidateRect and UpdateWindow pair instead.

Consider using the Visual Studio utility Spy++ to investigate the window hierarchy and relevant window properties when you have these bizarre buttons - oddities there (position, z-order, clipping related window styles) might give you a hint as to what is going wrong.

You may indeed be  right looking at some code of mine I used:

bret = RedrawWindow(ghwndMain, NULL,NULL,ior(RDW_ERASE,RDW_INVALIDATE))

but that invalidates the window region so that it all gets redrawn when a paint event next occurs, in some instances (do not as me why - there is indeed magic powers at play) I have found it useful to force a WM_PAINT.

0 Kudos
Simon_Geard
New Contributor I
2,854 Views

Thanks very much for your suggestions.

The call to CreateWindowEx causes the buttons to be created so at that point ghwndMain has not yet been set. I have tried all the other methods you suggest and none of them work. I'll investigate some more in a couple of weeks and post again when I get more info.

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

perhaps posting the CreateWindowEx call and the initialisations of the things you pass to it might shed some light.

You could also try doing  something with the buttons in the WM_CREATE event of the WinProc associate with the   CreateWindowEx

 

 

 

0 Kudos
Simon_Geard
New Contributor I
2,854 Views

Attached is a cut-down version of the code I'm using. I don't expect it to compile but it does contain all the window creation and message handling of the application.

Thanks again.

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

OK you create the child dialog under the WM_CREATE of the main winproc. I have never done it that way and in my mind it seems you are creating a child of the main window at a time when the main window it is still being born and is not fully formed.

I create my children either as a result of events such as menu picks handled by the winproc or in the case  where it is unconditionally created at startup I would call your CreateChildDialog in the main program after CreateWindowEx has completed but before lret = ShowWindow( ghwndMain, nCmdShow ). On the show window the main window and its children will be drawn.

 

 

 

0 Kudos
Simon_Geard
New Contributor I
2,854 Views

Ok. I've removed the calls in WM_CREATE and tried using

[fortran]
 

    ghwndMain = CreateWindowEx(  0, lpszClassName,                 &
                                 lpszAppName,                      &
                                 INT(WS_OVERLAPPED .or. WS_CAPTION .or. WS_SYSMENU .or. WS_MINIMIZEBOX  .or. WS_CLIPCHILDREN),         &
                                 CW_USEDEFAULT,                    &
                                 0,                                &
                                 gr_width,                         &
                                 gr_depth,                         &
                                 NULL,                             &
                                 ghMenu,                           &
                                 hInstance,                        &
                                 NULL                              &
                              )
    if (ghwndMain == 0) goto 99999
    lret = GetClientRect( ghwndMain, wrect)
    mainwin(:,1) = [wrect%left,wrect%top]
    mainwin(:,2) = [wrect%right,wrect%bottom]

           call CreateChildDialog(ghwndMain)
            call ResizeChildDialog(ghwndMain)
        
    lret = ShowWindow( ghwndMain, nCmdShow )


[/fortran]

but the result is the same as before, still no buttons until the main window is moved. It looks as if it's something to do with the message passing because if I uncomment line 226 in the attached file the buttons behave correctly - it's just nothing else works. Perhaps the buttons aren't getting the WM_PAINT message and I need my WM_PAINT action to be more selective.

0 Kudos
andrew_4619
Honored Contributor III
2,854 Views

Actually I was missing something big here. You did mention OGL in the initial post d'oh!.

I only see a couple of opengl commands in your code but I do not see a whole load of stuff that is needed to make an OGL compliant window. with a OGL compliant device context, pixel format etc. There is an example of such in the fortran samples. You need to apply OGL command within the OGL device context, I use a separate OGL window which has its own message loop but this does have some child dialogs that work OK so I am guessing that the OGL window can be the main window. 

 

 

0 Kudos
Reply