Roger
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
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
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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
ASKER
xtermie: Thanks for your point.
private void WorkbookBeforeCloseHandler (Excel.Wor kbook 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
private void WorkbookBeforeCloseHandler
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:
And post some code and screenshots..
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..
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_ConceptIconCrea tn_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_visMasterF ile_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(ByVa l Wn As Window)
'if under suitable conditions, ie AFTER the parent child windows have been formed:
'Application.ScreenUpdatin g = False
setVisWinSize
'Application.ScreenUpdatin g = 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).
If you have any tips for my question, they will be greatly appreciated.
Cheers!
Kelvin
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_ConceptIconCrea
Set visApp = New Visio.Application
visWindowHandle32 = visApp.WindowHandle32
SetParent visWindowHandle32, Excel.Application.hWnd
Set visDoc = visApp.Open(gbl_visMasterF
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(ByVa
'if under suitable conditions, ie AFTER the parent child windows have been formed:
'Application.ScreenUpdatin
setVisWinSize
'Application.ScreenUpdatin
'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).
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.
ASKER
That was an interesting interacion, thanks
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?