Link to home
Start Free TrialLog in
Avatar of Roger
RogerFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Excel 365 seeking an API or another way to Hide/Display Window Application.Close 'x' control

The Close 'x' button, highlights on a red background, and is located at the top right of the main Excel Window

I can use the API functions GetSystemMenu Lib, DeleteMenu Lib, EnableMenuItem Lib - to respectively disable and enable the the Close 'x' button (https://excelprovegue.wordpress.com/2016/11/06/disable-close-button/).

But I want to HIDE / DISPLAY that 'x'control.
How do I do that?

Thanks! Kelvin
Avatar of ste5an
ste5an
Flag of Germany image

No, you don't want to do that. Really.

This means changing the users experience with Windows, changing how the UI is designed to work. Users expect that button.

Thus the question: Why do you think you need to do this?
SOLUTION
Avatar of Anastasia D. Gavanas
Anastasia D. Gavanas
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Roger

ASKER

ste5an: Thank for your point about standardising user experience, but the user experience in my project is non-standard in several ways:

I run MS Visio as a child of excel: the Visio Window appears within the Excel window (and re-sizes with it).

This parent-child relationship results in no less than three  'x' ctls in the top right of the respective windows of: the xlApp, the visioApp, and the Viso.document (the latter being the 'drawing window'). The parent child relationship between xl and visio also means that closure of either xlApp or visioApp automatically closes BOTH applications.

My prospective users will not be particularly computer literate (they will be specialists in other subjects). So the presence of a stack of three 'x' ctls will be a challenge to the provision of a smooth experience, that prevents confusion, and secures the data output. I can INACTIVATE the xl window close 'x' ctl, and create replacement closure ctls in the xl fluent ribbon. But HIDING the xl window 'x' closure control would  help reduce the visual complexity in the upper right hand corner of the piece.

The replacement ribbon 'closure' ctls can be controlled contexturally. The ribbon is completely customised, and functions with customised ctls under its own contextural controls for both tab display and ctl display etc. [I've just seen your second comment: there is no problem controlling file-shut down from the ribbon, by now - its fairly standard for me].

If I have given a reasonable justification for my question, could you and/or colleague experts tell me if I can actually HIDE these window 'x' close ctls?  

Many thanks for picking up on this question; I accept your comments as a positive contribution.
Kelvin
Avatar of Roger

ASKER

xtermie: Thanks for your point.

private void WorkbookBeforeCloseHandler(Excel.Workbook Wb, ref bool Cancel)

Is this is like a QueryClose event (for workbook)? IE it does not HIDE the window 'x' closure ctl, but makes closure conditional on a context I provide? If so, I'd certainly need to use it to control closure via any closure button.

My itch is still to hide the 'x'clure ctl!

Kelvin
Can you elaborate this:

I run MS Visio as a child of excel: the Visio Window appears within the Excel window (and re-sizes with it).

 This parent-child relationship results in no less than three  'x' ctls in the top right of the respective windows of: the xlApp, the visioApp, and the Viso.document (the latter being the 'drawing window'). The parent child relationship between xl and visio also means that closure of either xlApp or visioApp automatically closes BOTH applications.

And post some code and screenshots..
Avatar of Roger

ASKER

@ste5an: OK, in outline.
Parent-Child windows. The clue came from Chip Pearson's comment about positioning a browser obj within excel:
https://www.pcreview.co.uk/threads/in-vba-make-ie-browser-object-always-in-foreground.2503326/

"To keep the browser visible within Excel, allowing you to switch between IE and Excel without losing the browser, you need to use the
SetParent API call."
In the declarations area of your module (above and outside of any
procedure), declare the SetParent function.

Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Then, in your procedure, use code like the following to make IE a child window of the Excel application, so IE
will float above the worksheet.

IE.Visible = True
SetParent IE.Hwnd, Application.Hwnd
---------------------------

In my hands that became
sub makeParent_Child()
        Dim visWindowHandle32 As Long
   
    gbl_Master_ConceptIconCreatn_File = "C:..path to .vsdm child file"
   
    Set visApp = New Visio.Application
    visWindowHandle32 = visApp.WindowHandle32    
    SetParent visWindowHandle32, Excel.Application.hWnd
    Set visDoc = visApp.Open(gbl_visMasterFile_path)

    setVisWinSize 'below
end sub

Sub setVisWinSize()
    'Excel window: hWndSource
    'Visio window:  hWndDest
    Dim r As RECT
    Dim wins As Visio.Windows
    Dim win As Visio.Window
    Dim appWin As Visio.Window
    Dim w As Long
    Dim h As Long
 
    Set appWin = visApp.Window

    'Get the Excel window and position
    GetWindowRect FindWindow("XLMAIN", vbNullString), r
    w = r.Right - r.Left
    h = r.Bottom - r.Top
   
    appWin.SetWindowRect 10, 200, w - 20, h - 200
End Sub

'to resize visio child when xl window re-sizes, call setVisWinSize from event:
Private Sub Workbook_WindowResize(ByVal Wn As Window)
    'if under suitable conditions, ie AFTER the parent child windows have been formed:
        'Application.ScreenUpdating = False
            setVisWinSize
        'Application.ScreenUpdating = True
    'end if
End Sub

Appearance:  xl ribbon green as usual, at the top.In the xl Window, is the VisioApp.window, which contains the Visio.Doc window ('drawing window). Drag the xl window; the visio window moves with it. Resize xl window; visio resizes automatically. Click App Window  'x' close ctl button on either xl or visio - and both parent and child close (on the single click).

User generated image
If you have any tips for my question, they will be greatly appreciated.
Cheers!
Kelvin
Well, I would try hidding the inner windows border using SetWindowLong(). I never tried it on Office application window, but it may work.
Avatar of Roger

ASKER

That was an interesting interacion, thanks