En-/Disable Window Min, Max & Close Buttons

Share your advanced PureBasic knowledge/code with the community.
Axolotl
Addict
Addict
Posts: 831
Joined: Wed Dec 31, 2008 3:36 pm

Re: En-/Disable Window Min, Max & Close Buttons

Post by Axolotl »

HI,
try this.

Code: Select all

Procedure IsXEnabled(hWnd)
  mii.MENUITEMINFO
  mii\cbSize=SizeOf(MENUITEMINFO)
  mii\fMask=#MIIM_STATE
  result=999
  GetSystemMenu_(hWnd, #True)
  hSysMenu=GetSystemMenu_(hWnd,#False)
  Debug hSysMenu ; 374605515 (OK)
  If hSysMenu
    info=GetMenuItemInfo_(hSysMenu,#SC_CLOSE, 0, @mii)
    Debug info ; 0 (Failure)
    If info
      result=Bool(mii\fState=#MFS_ENABLED)
    EndIf
  EndIf
  ProcedureReturn result
EndProcedure

hWnd=FindWindow_(0,"Untitled - Notepad") ; "Unbenannt - Editor"  "Untitled - Notepad"
If hWnd=0
  Debug "Please start Notepad manually and run this code TWICE to see the problem!"
Else
  Debug IsXEnabled(hWnd) ; Returns 999 on SECOND run because "info" var is 0 (failed).
EndIf 

EDit: Sorry, had to change to the english version of Notepad.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4953
Joined: Sun Apr 12, 2009 6:27 am

Re: En-/Disable Window Min, Max & Close Buttons

Post by RASHAD »

Hi guys

Code: Select all

appl$ = "Document - WordPad"

mii.MENUITEMINFO
mii\cbSize=SizeOf(MENUITEMINFO)
mii\fMask=#MIIM_STATE

; Disable Close(#MF_DISABLED not working anymore for Windows 10 because of Alt-F4)
Repeat 
  hWnd=FindWindow_(0,appl$) 
  x + 1
Until hwnd Or x > 5000
If x > 5000
  MessageRequester("Error","Please run the application first",#MB_OK)
  End
EndIf

hSysMenu = GetSystemMenu_(hWnd, #False)
If hSysMenu
  EnableMenuItem_(hSysMenu, #SC_CLOSE, #MF_BYCOMMAND | #MF_GRAYED	)
  DrawMenuBar_(hWnd)
  GetMenuItemInfo_(hSysMenu,#SC_CLOSE, 0, @mii)
  Debug Bool(mii\fState=#MFS_ENABLED)
EndIf

Delay(1000)

;Enable Close
Repeat 
  hWnd=FindWindow_(0,appl$) 
Until hwnd
GetSystemMenu_(hWnd, #True)
hSysMenu = GetSystemMenu_(hWnd,#False)
If hSysMenu
  EnableMenuItem_(hSysMenu, #SC_CLOSE, #MF_BYCOMMAND | #MF_ENABLED)
  DrawMenuBar_(hWnd)
  GetMenuItemInfo_(hSysMenu,#SC_CLOSE, 0, @mii)
  Debug Bool(mii\fState=#MFS_ENABLED)
EndIf

;Refresh the application
Repeat 
  hWnd=FindWindow_(0,appl$)
Until hwnd
GetSystemMenu_(hWnd, #True)
EnableMenuItem_(hSysMenu, #SC_CLOSE, #MF_BYCOMMAND | #MF_ENABLED)
DrawMenuBar_(hWnd)

Edit : Modified 4 Application
Egypt my love
BarryG
Addict
Addict
Posts: 4167
Joined: Thu Apr 18, 2019 8:17 am

Re: En-/Disable Window Min, Max & Close Buttons

Post by BarryG »

Rashad, your routines work great to disable/enable the Close button, thanks!

Axolotl, your new code still doesn't work: if I run it on a disabled Close button on Notepad (see below), then it enables the Close button instead of just reporting the state.

Code: Select all

Procedure IsXEnabled(hWnd)
  mii.MENUITEMINFO
  mii\cbSize=SizeOf(MENUITEMINFO)
  mii\fMask=#MIIM_STATE
  GetSystemMenu_(hWnd, #True)
  hSysMenu=GetSystemMenu_(hWnd,#False)
  If hSysMenu
    info=GetMenuItemInfo_(hSysMenu,#SC_CLOSE, 0, @mii)
    If info
      result=Bool(mii\fState=#MFS_ENABLED)
    EndIf
  EndIf
  ProcedureReturn result
EndProcedure

Debug IsXEnabled(FindWindow_(0,"Untitled - Notepad")) ; Enables a disabled Close button on Notepad.
Axolotl
Addict
Addict
Posts: 831
Joined: Wed Dec 31, 2008 3:36 pm

Re: En-/Disable Window Min, Max & Close Buttons

Post by Axolotl »

BarryG,

I am glad RASHADs solution works for you.

Sorry for stealing your time, but I guess I didn't really understand your problem.

Anyway, for my understanding there is this strange behavior of GetMenuItemInfo_() on 'second calls'.
Some observations which I have gathered so far:

The second calls of GetMenuItemInfo_ are showing an error acc. to MSDN: ERROR_INVALID_PARAMETER 87 (0x57) The parameter is incorrect.

It can be fixed by calling GetSystemMenu_(hWnd, #True)
But, that resets the SystemMenu and you loose the existing state (only if it was disabled), but you never know. :oops:
After that Reset the default state is enabled again.

At this point, I'm afraid I have to give up :? :(
and I refrain from sending the last state of my code, because the error still appears.

BTW: Without changing the state before reading it, it is possible that the mii\fState member also gets the #MFS_DEFAULT flag ($1000).
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
BarryG
Addict
Addict
Posts: 4167
Joined: Thu Apr 18, 2019 8:17 am

Re: En-/Disable Window Min, Max & Close Buttons

Post by BarryG »

Axolotl wrote:It can be fixed by calling GetSystemMenu_(hWnd, #True)
But, that resets the SystemMenu and you loose the existing state (only if it was disabled), but you never know. :oops:
After that Reset the default state is enabled again.
Axolotl, yes, it does seem to re-enable it when reading it, so it's unreliable. Thanks for trying, anyway.

At the moment I've done a (dodgy) workaround by setting a toggle prop for the window whenever I change its Close button state. Works perfectly, but of course I have to assume a default state for the window, which I've chosen to be as "enabled" even though it may be disabled. Meh. Near enough is good enough, as I guess 99% of the time an app's Close button will be enabled when the app starts.
BarryG
Addict
Addict
Posts: 4167
Joined: Thu Apr 18, 2019 8:17 am

Re: En-/Disable Window Min, Max & Close Buttons

Post by BarryG »

Sorry to drag this up again... it doesn't work with Win 10 app windows, like the Win 10 Calculator. It only works with Win32 executables. Is it an easy fix?
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4953
Joined: Sun Apr 12, 2009 6:27 am

Re: En-/Disable Window Min, Max & Close Buttons

Post by RASHAD »

Hi BarryG
Calculator has no System Menu
It is a special class like some other MS applications
Egypt my love
Post Reply