Is it possible to disable the closure of a window

J_Koeleman

New Member
I was wondering if it's possible to disable the cross-button on the top right, so it isn't possible to close the window?

There is a MIN-BUTTON and a MAX-BUTTON attribute of the window handle but an EXIT-BUTTON handle is not available.

Does anybody know a way to get this done?
 
Perheps anyboady knows a way to get it enabled again. The opposit function of RemoveMenu (the function used in the above suggested working code) is AppendMenu. But I can't get that one working.

Searching for examples I found another function: EnableMenuItem. Is there anybody who has experiance with this function in Progress?
 
I found a way to solve this problem, its an addition to the global-shared code (so use their code and edit that, there will be a bit unused code but you can delete that manually):

declare two extra preprosessors:


&GLOBAL-DEFINE MF_GRAYED 1
&GLOBAL-DEFINE MF_ENABLED 0


and declare another function:


PROCEDURE EnableMenuItem EXTERNAL "user32":
DEFINE INPUT PARAMETER hMenu AS LONG.
DEFINE INPUT PARAMETER uIDEnableItem AS LONG.
DEFINE INPUT PARAMETER uEnable AS LONG.
DEFINE RETURN PARAMETER iRetCode AS LONG.
END.


then you cold use this function to disable:


FUNCTION XPDisableMenuItem RETURNS LOGICAL
( ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
define var hSysMenu as int no-undo.
define var hParent as int no-undo.
define var hInstance as int no-undo.
define var iRetCode as int no-undo.
define var iCnt as int no-undo.
run GetParent(input {&window-name}:hWnd,
output hParent).
/* Get handle to our the window's system menu (Restore, Maximize, Move, close etc.) */
run GetSystemMenu(input hParent,
input 0,
output hSysMenu).

if hSysMenu <> 0 then
do:
/* Get System menu's menu count */
run GetMenuItemCount(input hSysMenu,
output iCnt).
IF iCnt <> 0 then
do:
RUN EnableMenuItem (input hSysMenu,input iCnt - 1,INPUT {&MF_BYPOSITION} + {&MF_GRAYED},OUTPUT iRetCode).

/* Force caption bar's refresh which will disable the window close ("X") button */
run DrawMenuBar(input hParent,output iRetCode).
end. /* if iCnt <> 0... */
end. /* if hSysMenu <> 0... */
RETURN FALSE. /* Function return value. */
END FUNCTION.


And this one to enable


FUNCTION XPEnableMenuItem RETURNS LOGICAL
( ) :
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
define var hSysMenu as int no-undo.
define var hParent as int no-undo.
define var hInstance as int no-undo.
define var iRetCode as int no-undo.
define var iCnt as int no-undo.
run GetParent(input {&window-name}:hWnd,
output hParent).
/* Get handle to our the window's system menu (Restore, Maximize, Move, close etc.) */
run GetSystemMenu(input hParent,
input 0,
output hSysMenu).

if hSysMenu <> 0 then
do:
/* Get System menu's menu count */
run GetMenuItemCount(input hSysMenu,
output iCnt).
IF iCnt <> 0 then
do:
RUN EnableMenuItem (input hSysMenu,input iCnt - 1,INPUT {&MF_BYPOSITION} + {&MF_ENABLED},OUTPUT iRetCode).

/* Force caption bar's refresh which will disable the window close ("X") button */
run DrawMenuBar(input hParent,output iRetCode).
end. /* if iCnt <> 0... */
end. /* if hSysMenu <> 0... */
RETURN FALSE. /* Function return value. */
END FUNCTION.
 
????

Head scratching here.
Why do you wish to disable the x / window close button?
That IS NOT standard Windows look-and-feel / behaviour.
The simplest way would be to on the window-close trigger place your bespoke validation which would have a RETURN NO-APPLY statement to drop out of that trigger. This would make it so, that trigger does nothing. Then you can have an exit in your UI as wished. DO NOT interfer with Bills standard behaviour. M$ Standard functionality is a given as the industry standard. Apply your own bespoke behaviour to exit the application how you choose, do not mess with Windows.
 
I agree completely... It's not just the fact that you will be playing around with the Windows Internals, but there is no guarantee that this will work in future versions of Windoze (if there ever is one lol). A simple RETURN NO-APPLY in the CLOSE event of the window should indeed do the trick just fine.

However, there are always people (read customers) that want things done that Bill & co. did not intend to happen - no matter how hard you try to convince them not to do those kind of things. As you will probably know, there is nothing worse than having to deal with to someone that *thinks* he/she knows everything simply because they have "written" an "application" in MS-Access and/or Visual Basic. And, if that is the case, well, the customer pays (although I personally would give plenty written warning that whatever they want may not work in future versions of Windows so there is no warranty on the solution and also state that it is against common and accepted rules of UI design for the Windows platform).

Anyway, I assume (or hope) the developer in question has tried the 4GL way of doing things and now has his own reasons to go down this path...
 
Back
Top