MessageBox with disabled OK button

Just starting out? Need help? Post your questions and find answers here.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

MessageBox with disabled OK button

Post by PB »

I need a MessageBox with a disabled OK button for two seconds.
After two seconds, the OK button should be enabled again.

The following code half-works, but if you uncomment the lines,
you'll see that it fails miserably. This is because the OK button
is only getting disabled by repeated calls of EnableWindow_(),
due to the thread running. I tried pausing/resuming the thread
but then the OK button is enabled after pausing. It's weird.

And yes, I know about "just use a custom window". I don't want
to, and besides, I want to know if a MessageBox can do it. :P

Code: Select all

Procedure MessageBoxDisabledThread(null)
  Repeat
    Sleep_(1)
    mb=FindWindow_(0,"Hello")
    If mb
      ok=GetWindow_(mb,#GW_CHILD)
      EnableWindow_(ok,0)
      ;Sleep_(2000)
      ;EnableWindow_(ok,1)
    EndIf
  ForEver
EndProcedure

CreateThread(@MessageBoxDisabledThread(),0)

MessageBox_(0,"This is the body","Hello",#MB_ICONINFORMATION)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4664
Joined: Sun Apr 12, 2009 6:27 am

Re: MessageBox with disabled OK button

Post by RASHAD »

"ForEver" :wink:

Code: Select all

Procedure MessageBoxDisabledThread(null)
  Repeat
    Sleep_(1)
    mb=FindWindow_(0,"Hello")
    If mb
      ok=GetWindow_(mb,#GW_CHILD)
      EnableWindow_(ok,0)
      Sleep_(2000)
      Result =  EnableWindow_(ok,1)
    EndIf
  Until Result > 0
EndProcedure

CreateThread(@MessageBoxDisabledThread(),0)

MessageBox_(0,"This is the body","Hello",#MB_ICONINFORMATION)
Egypt my love
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MessageBox with disabled OK button

Post by PB »

Rashad, I almost got excited by your reply but when I ran it,
it shows OK enabled for 2 seconds, then disabled for 2, and
then enabled. So, it doesn't quite work. I'm playing with it.

[Edit] Okay, got it sorted. Needed a small delay before the
"ok=GetWindow_(mb,#GW_CHILD)" line. This works fine:

Code: Select all

Procedure MessageBoxDisabledThread(null)
  Repeat
    Sleep_(1)
    mb=FindWindow_(0,"Hello")
    If mb
      Sleep_(10) ; REQUIRED!
      ok=GetWindow_(mb,#GW_CHILD)
      EnableWindow_(ok,0)
      Sleep_(2000)
      Result =  EnableWindow_(ok,1)
    EndIf
  Until Result > 0
EndProcedure

CreateThread(@MessageBoxDisabledThread(),0)

MessageBox_(0,"This is the body","Hello",#MB_ICONINFORMATION)
Thanks for your assistance! :D
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4664
Joined: Sun Apr 12, 2009 6:27 am

Re: MessageBox with disabled OK button

Post by RASHAD »

Good
Try it this way I think it is much better

Code: Select all

Procedure MessageBoxDisabledThread(null)
  Repeat
    Sleep_(1)
    mb=FindWindow_(0,"Hello")
    ok=GetWindow_(mb,#GW_CHILD)
  Until ok    
      EnableWindow_(ok,0)
      Sleep_(2000)      
      EnableWindow_(ok,1)
EndProcedure

CreateThread(@MessageBoxDisabledThread(),0)

MessageBox_(0,"This is the body","Hello",#MB_ICONINFORMATION)
Egypt my love
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MessageBox with disabled OK button

Post by PB »

MUCH nicer and works here just fine. Thanks again! :D
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: MessageBox with disabled OK button

Post by netmaestro »

Here's a packaged turnkey solution in its own black box that allows for:
- Choosable number of milliseconds to wait
- Any style of requester, all buttons will start disabled and then auto-enable after the delay

Code: Select all

DeclareModule WaitBox
  Declare Show(title$, text$, wait, flags=0)
EndDeclareModule

Module WaitBox
  Global mr_hook
  Global NewList buttons.i()
  
  Procedure mr_hookProc(nCode, wParam, lParam)
    Select nCode
      Case #HCBT_CREATEWND
        *pcbt.CBT_CREATEWND = lParam 
        *pcs.CREATESTRUCT = *pcbt\lpcs 
        Select *pcs\lpszClass
          Case $C017 ; Button
            EnableWindow_(wparam, 0)
            AddElement(buttons())
            buttons()=wparam
        EndSelect
        ProcedureReturn 0
    EndSelect
    ProcedureReturn CallNextHookEx_(mr_hook, nCode, wParam, lParam) 
  EndProcedure
  
  Procedure wait(time)
    Delay(time)
    ForEach buttons()
      EnableWindow_(buttons(), 1)
    Next
    FreeList(buttons())
  EndProcedure
  
  Procedure Show(title$, text$, wait, flags=0)
    CreateThread(@wait(), wait)
    mr_hook = SetWindowsHookEx_(#WH_CBT, @mr_hookProc(), #Null, GetCurrentThreadId_()) 
    result  = MessageRequester(title$, text$, flags)
    UnhookWindowsHookEx_(mr_hook)
    ProcedureReturn result
  EndProcedure
  
EndModule

; Test it
result = WaitBox::Show( "", "//TODO: Wait five seconds", 5000, #PB_MessageRequester_YesNoCancel)
Select result
  Case #PB_MessageRequester_Yes
    Debug "you said yes, so I guess it's ok"
  Case #PB_MessageRequester_Cancel
    Debug "well, that was worthwhile..."
  Case #PB_MessageRequester_No
    Debug "well, no means no, thanks anyway"
EndSelect
BERESHEIT
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4664
Joined: Sun Apr 12, 2009 6:27 am

Re: MessageBox with disabled OK button

Post by RASHAD »

- 2 sec to enable the keys ( select the time as you wish )
- 10 sec to answer or your answer will be NO

Code: Select all

Procedure MessageBoxDisabledThread(parameter)
  Repeat
    Sleep_(1)
    mb=FindWindow_(0,"Hello")
    btn=GetWindow_(mb,#GW_CHILD)
    btn2=GetWindow_(btn,#GW_HWNDNEXT)
    btn3=GetWindow_(btn2,#GW_HWNDNEXT)
  Until btn3   
    EnableWindow_(btn,0)
    EnableWindow_(btn2,0)
    EnableWindow_(btn3,0)
    
    Sleep_(parameter)
         
    EnableWindow_(btn,1)
    EnableWindow_(btn2,1)
    EnableWindow_(btn3,1)
    
    Sleep_(10000)
    
    PostMessage_(btn2, #WM_LBUTTONDOWN, 0, 0)
    PostMessage_(btn2, #WM_LBUTTONUP, 0, 0)
EndProcedure

CreateThread(@MessageBoxDisabledThread(),2000)

Result = MessageBox_(0,"Do you want to continue ?","Hello",#MB_YESNOCANCEL|#MB_ICONQUESTION)

Select Result
   Case #IDYES
      Debug "You clicked YES key"
   Case #IDNO	      
      Debug "You clicked NO key"
   Case #IDCANCEL	
      Debug "You clicked CANCEL key"
EndSelect
Egypt my love
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: MessageBox with disabled OK button

Post by PB »

Just for the record: only netmaestro's version is acceptable,
because the user can just press the Space bar on all others
to "click" the button (even though the button is disabled).

So, just posting this for future reference, because I always
assumed the other tips were fine until I accidentally pressed
Space on them today. :shock:
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply